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

posted @ 2020-04-01 14:55  kissrule  阅读(236)  评论(0编辑  收藏  举报