unsafe.Pointer uintptr
unsafe
针对刚刚的 “错误示例”,我们可以采用今天的男主角 unsafe
标准库来解决。它是一个神奇的包,在官方的诠释中,有如下概述:
- 围绕 Go 程序内存安全及类型的操作
- 很可能会是不可移植的
- 不受 Go 1 兼容性指南的保护
简单来讲就是,不怎么推荐你使用。因为它是 unsafe(不安全的),但是在特殊的场景下,使用了它。可以打破 Go 的类型和内存安全机制,让你获得眼前一亮的惊喜效果 😄
Pointer
为了解决这个问题,需要用到 unsafe.Pointer
。它表示任意类型且可寻址的指针值,可以在不同的指针类型之间进行转换(类似 C 语言的 void * 的用途)
其包含四种核心操作:
- 任何类型的指针值都可以转换为 Pointer
- Pointer 可以转换为任何类型的指针值
- uintptr 可以转换为 Pointer
- Pointer 可以转换为 uintptr
1、uintptr:
uintptr
是 Go 的内置类型。返回无符号整数,可存储一个完整的地址。后续常用于指针运算#ifdef _64BIT
typedef uint64 uintptr;
typedef int64 intptr;
typedef int64 intgo; // Go's int
typedef uint64 uintgo; // Go's uint
#else
typedef uint32 uintptr;
typedef int32 intptr;
typedef int32 intgo; // Go's int
typedef uint32 uintgo; // Go's uint
#endif
这里存在一个问题,uintptr
类型是不能存储在临时变量中的。因为从 GC 的角度来看,uintptr
类型的临时变量只是一个无符号整数,并不知道它是一个指针地址
因此当满足一定条件后,ptr
这个临时变量是可能被垃圾回收掉的,那么接下来的内存操作,岂不成迷?
链接:https://www.jianshu.com/p/fb25dce48317