Go语言中的非类型安全指针

发布于:2025-07-30 ⋅ 阅读:(23) ⋅ 点赞:(0)

介绍:

        Golang 语言中的unsafe 包中包含的操作绕过了Golang 程序的类型安全检查,直接操作内存,从而达到提升性能的目的,导入unsafe 包可能是不可移植的,并且不受 Go1 兼容性准则的保护,所以我们应该谨慎使用。

       下面主要介绍unsafe 包的 unsafe.Pointer ,它表示任意类型的指针,他类似于C语言中的无类型指针,void* , 可以作为指针类型 * T 和 uintptr 类型值之间相互转换的中转站。

        我们知道 Golang 语言中指针类型是 * T ,表示一个指向T类型变量的指针,因为Golang  语言是强类型的静态语言, 为了安全考虑,规定两个不同的指针类型之间不可以相互转换,比如 *int 不能与 * float32  相互转换,但是,实际上是可以使用 unsafe.Pointer  进行转换。

        在比如Golang 语言中的内置数据类型,uintptr  也可以表示任何指针,它实际的数值类型,可以用于存储内存地址。它和unsafe.Pointer 最大的区别是 unsafe.Pointer 不支持指针运算,比如 + 运算符 ,但是 uintptr 可以支持。

unsafe.Ponter 类型

        有了前面内容的铺垫,我们开始介绍unsafe.Ponter ,它表示指向任意类型的指针,以下是unsafe 的代码。

type ArbitraryType int
type Pointer *ArbitraryType

unsafe.Ponter 类型有四个准换规则:

  1. 任何类型的指针值*T  都可以转换位unsafe.Pointer
  2. unsafe.Pointer  可以转换为任何类型的指针值。
  3. uintptr 可以转换为unsafe.Pointer
  4. unsafe.Pointer 可以转换为 uintptr。

unsafe.Pointer  允许程序绕过类型安全检查读写任意内存,所以使用适应格外小心。

unsafe.Pointer 包含6个使用模式。

  • 使用 unsafe.Pointer 作为中转,将一个指针类型 *T 转换为另外一个指针类型 *T

  • 将 unsafe.Pointer 转换为 uintptr(但不返回给 unsafe.Pointer),然后使用 uintptr 值。

  • 将 unsafe.Pointer 转换为 uintptr,然后使用 uintptr 值进行算术运算,最后将运算结果 uintptr 值再转换为 unsafe.Pointer

  • 调用 syscall.Syscall 时,将 unsafe.Pointer 转换为 uintptr 值,作为参数传递。

  • 将 reflect.Value.Pointer 或 reflect.Value.UnsafeAddr 的返回结果 uintptr 值,从 uintptr 转换为 unsafe.Pointer

  • 将 reflect.SliceHeader 或 reflect.StringHeader 值的 Data 字段与 unsafe.Pointer 进行转换。

     


网站公告

今日签到

点亮在社区的每一天
去签到