结构体的成员变量在内存存储上是一段连续的内存
- 结构体的初始地址就是第一个成员变量的内存地址
- 基于结构体的成员地址去计算偏移量。就能够得出其他成员变量的内存地址
unsafe.Pointer是一个指针类型
- 值不能被取消引用?
- 如果unsafe.Pointer变量仍然有效,则由unsafe.Pointer变量表示的地址处的数据不会被GC回收
- 实质是int类型
- 不可以参与指针运算
uintptr是一个整数类型
- 即使uintptr变量仍然有效,由uintptr变量表示的地址处的数据也可能被GC回收
- uintptr 是 Go 的内置类型,返回无符号整数
- 可存储一个完整的地址。后续常用于指针运算
- C语言中有一个uintptr_t类型不同位数处理器对应不同定义,用于存放地址
- 可以参与指针运算
- 将uintptr转为unsafe.Pointer指针可能会破坏类型系统,因为并不是所有的数字都是有效的内存地址
unsafe.Offsetof
- 返回变量的字节大小,也就是本文用到的偏移量大小
指针对性能的负面影响
- 解引用消耗
- 垃圾回收
指针运算
var arr [2]int64
arr = [2]int64{
4, 44,
}
p := uintptr(unsafe.Pointer(&arr))
pp := (*int64)(unsafe.Pointer(p + 8))//这一行执行的时候p执行的地址已经被移动
*pp = 66
for _, v := range arr {
println(v)
}
参考资料: