结构体的成员变量在内存存储上是一段连续的内存

  • 结构体的初始地址就是第一个成员变量的内存地址
  • 基于结构体的成员地址去计算偏移量。就能够得出其他成员变量的内存地址

unsafe.Pointer是一个指针类型

  1. 值不能被取消引用?
  2. 如果unsafe.Pointer变量仍然有效,则由unsafe.Pointer变量表示的地址处的数据不会被GC回收
  3. 实质是int类型
  4. 不可以参与指针运算

 

uintptr是一个整数类型

  1. 即使uintptr变量仍然有效,由uintptr变量表示的地址处的数据也可能被GC回收
  2. uintptr 是 Go 的内置类型,返回无符号整数
  3. 可存储一个完整的地址。后续常用于指针运算
  4. C语言中有一个uintptr_t类型不同位数处理器对应不同定义,用于存放地址
  5. 可以参与指针运算
  6. 将uintptr转为unsafe.Pointer指针可能会破坏类型系统,因为并不是所有的数字都是有效的内存地址

unsafe.Offsetof

  1. 返回变量的字节大小,也就是本文用到的偏移量大小

指针对性能的负面影响

  1. 解引用消耗
  2. 垃圾回收

指针运算

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)

}

 

参考资料: