在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事.
hacking is happy!!! ;]
如标题所说,现在我有一个Int变量x,我想取得它的地址,然后转换为Char类型的地址,然后将改地址的内容+1,如果用C语言来表示就是:
int x = 121,*pi = &x
char *pc = (char *)pi
*pc += 1
用Swift来写有2个问题,一是你没法直接得到一个变量的指针,二是即使你可以,你也不能直接在两种不同类型的指针直接转换.
我们先来解决第一个问题,你不能这样写:
var x:Int = 121
var px = &x //error!!!
问题不在于那个&操作符,很多人可能以为Swift没有C中取地址操作符&,可实际上是有的,但是你不能将取得的地址直接再做处理.
不过有办法,我们可以用withUnsafePointer方法的变体withUnsafeMutablePointer方法来取得其地址,只不过该地址作为一个参数传到你指定的闭包中.只要能得到地址,你还有什么奢求呢?
typealias Char = Int8
var x = 121
var pChar = withUnsafeMutablePointer(&x){(p:UnsafeMutablePointer<Int>)->UnsafeMutablePointer<Char> in
//???
}
如上代码我们只要在闭包中返回一个Char指针就可以了,怎么做呢?
这就需要借助另一个超级强大(你懂得”强大”在这里是什么意思;])的方法unsafeBitCast,该方法将一种类型的变量内容强制转换为另一种,将以上闭包的//???处替换为如下代码:
return unsafeBitCast(p,UnsafeMutablePointer<Char>.self)
好了,我们来测试一下:
注意上图的最后一行最后的数字377,x为啥从121变为377呢?这里不予解释,因为常玩汇编或C的小伙伴肯定早就了然于心鸟! ;]