golang unsafe 和 uintptr 指针
1.golang中的指针类型
三个类型
其实指针有三种:
一种是我们常见的*,用*去表示的指针;
一种是unsafe.Pointer,Pointer是unsafe包下的一个类型;
最后一种是uintptr,uintptr 这玩意是可以进行运算的也就是可以++–;
他们之间有这样的转换关系:
*<=> unsafe.Pointer <=> uintptr
有一点要注意的是,uintptr 并没有指针的语义,意思就是 uintptr 所指向的对象会被 gc 无情地回收。而 unsafe.Pointer 有指针语义,可以保护它所指向的对象在“有用”的时候不会被垃圾回收。
从这样的关系你大概就可以猜到,我们使用的指针*p转换成Pointer然后转换uintptr进行运算之后再原路返回,理论上就能等同于进行了指针的运算。我们下面就来实践一下。
2.具体操作
unsafe操作slice
func main() {
s := make([]int, 10)
s[1] = 2
p := &s[0]
fmt.Println(*p)
up := uintptr(unsafe.Pointer(p)) //这里有可能会被回收 所以最好写成 (*int)unsafe.Pointer(uintptr(unsafe.Pointer(p))+unsafe.Sizeof(int(0)))
up += unsafe.Sizeof(int(0)) // 这里不是up++
p2 := (*</