Pointer 指针 #
Go 中指针分为两种:
- 类型安全指针(如 *int, *string)
 - 非类型安全指针(unsafe.Pointer)
 
关于 uintptr :是一个无符号的整型,Go 的基本类型之一。主要用在为非类型安全指针(unsafe.Pointer)实现数值计算。
类型安全指针 #
Go (类型安全)指针的限制:
- Go 指针不能支持算术运算(如 
p++) - 一个指针类型的值不能被随意转换为另一个指针类型
 - 一个指针值不能和其它任一指针类型的值进行比较(需要满足以下任意一个条件):
- 指针类型相同。
 - 一个指针可以被隐式转换为另一个指针的类型。
 - 其中一个且只有一个指针为 
nil。 
 - 一个指针值不能被赋值给其它任意类型的指针值
 
如果需要打破以上规则,则需要使用 unsafe.Pointer。
  非类型安全指针 unsafe.Pointer
  #
只有以下六种使用 unsafe.Pointer 的方式是“合法”的:
- 将 
*T1转换为unsafe.Pointer转换为*T2(将值从类型T1转换成T2)。func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } - 将 
unsafe.Pointer转换为uintptr(但不能再把它转回unsafe.Pointer) - 将 
unsafe.Pointer转换为uintptr,执行数学运算后再转回unsafe.Pointer。(转换前后的指针必须指向同一个分配的内存块)(转换和运算必须在同一语句中,不能将其分开【可能会被 GC】)// equivalent to f := unsafe.Pointer(&s.f) f := unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f)) - 将 
unsafe.Pointer转换成uintptr并传给syscall.Syscall调用。【编译器赋予syscall.Syscall的特权】 - 将 
reflect.Value.Pointer或reflect.Value.UnsafeAddr的返回值从uintptr转换成unsafe.Pointer(也必须写在同一语句中,否则相应内存被 GC 的风险)。 
p := (*int)(unsafe.Pointer(reflect.ValueOf(new(int)).Pointer()))
- 将 
reflect.SliceHeader或reflect.StringHeader的Data字段(uintptr类型)转换为unsafe.Pointer或反转。