go unsafe package 的学习

来源:互联网 发布:物流软件app是什么意思 编辑:程序博客网 时间:2024/06/11 21:37

go 不像c 那样直接可以对指针做一些操作,所以go 提供了一个标准的package 来操作指针。go 有三种指针类型:
1.  *  普通指针, 用于传递对象地址,不能进行指针运算

2.  unsafe.Pointer:通用指针类型,用于转换不同类型的指针,不能进行指针运算。

3.  uintptr:用于指针运算,GC 不把 uintptr 当指针,uintptr 无法持有对象。uintptr 类型的目标会被回收


unsafe.Pointer 可以和 普通指针 进行相互转换, unsafe.Pointer 可以和 uintptr 进行相互转换; 也就是说 unsafe.Pointer 是桥梁,可以让任意类型的指针实现相互转换,也可以将任意类型的指针转换为 uintptr 进行指针运算

我们可以看下面的code: 

package mainimport ("fmt""unsafe")func main() {s := struct {a byteb bytec byted int64}{0, 0, 0, 0}p := unsafe.Pointer(&s)up0 := uintptr(p)pb := (*byte)(p)*pb = 10fmt.Println(s)     // 10, 0, 0 , 0up := up0 + unsafe.Offsetof(s.b)p = unsafe.Pointer(up)pb = (*byte)(p)*pb = 20fmt.Println(s)   //10, 20, 0, 0up = up0 + unsafe.Offsetof(s.c)p = unsafe.Pointer(up)pb = (*byte)(p)*pb = 30fmt.Println(s)   // 10, 20, 30. 0up = up0 + unsafe.Offsetof(s.d)p = unsafe.Pointer(up)pi := (*int64)(p)*pi = 40fmt.Println(s)    //10, 20, 30, 40 }



每种类型都有它的大小和对齐值,可以通过 unsafe.Sizeof 获取其大小,通过 unsafe.Alignof 获取其对齐值,通过 unsafe.Offsetof 获取其偏移量。不过 unsafe.Alignof 获取到的对齐值只是该类型单独使用时的对齐值,不是作为结构体字段时与其它对象间的对齐值,这里用不上,所以需要用 unsafe.Offsetof 来获取字段的偏移量,进而确定其内存地址



原创粉丝点击