uintptr
和 unsafe.Pointer
都属于 Go 语言中的指针类型,内部实现方式略有不同。
首先我们知道,任何指针都有一个地址(也就是指向的内存单元的位置)以及一些其他的元数据,比如类型信息、大小等等,这些元数据存储在指针本身所指向的内存单元中。在 Go 语言中使用的指针类型中,uintptr 和 unsafe.Pointer 之间并没有太大的区别,基本可以互换使用,但是具体使用时需要提及到一些细节。
uintptr
的定义:uintptr
是 Go 语言中的一种整数类型,可以用来存储一个指针类型的值。此类型的值不会被回收,所以它引用的对象将不会成为垃圾对象。uintptr 类型的值可以在对指针进行转换时使用,因为在 Go 中,指针可以自由地转换为任意类型的指针。unsafe.Pointer
的定义:unsafe.Pointer
是 Go 语言标准库中的一个类型。它可以用来存储任意类型的指针,这包括所有的指针类型,甚至是函数指针。该类型应该谨慎使用,因为它将绕过所有的类型安全机制,容易导致程序崩溃和内存泄漏等问题。
从上面的定义可以看出,uintptr
是一种无类型指针,实际上它只是一个字段,保存了指向的内存单元的地址,没有类型标识。而unsafe.Pointer
是一种从指针类型向另一种指针类型不安全转换的工具,可以保存任何类型的地址,并允许对其进行指针算术运算(如加减操作)甚至直接使用(如打印指针地址)。它常用于将指针转换为指向未定义类型的指针,并允许进行类型转换、算术运算以及向内存的任意位置写入数据等操作。
在使用时,如果需要将任意类型的指针转换为 uintptr
类型,则需要使用 Go 语言中的 unsafe
包中的 uintptr
函数。而如果需要将 uintptr
类型的指针转换为任意类型的指针,则需要使用 unsafe.Pointer
函数。
需要注意的是,使用 uintptr
类型的指针时要格外小心,因为 Go 语言的内存分配方式和垃圾回收机制可能会使地址变更。如果使用了一个被移动过的内存地址,那么很可能会引发不可预知的错误。此外,对于内存安全这一特性, uintptr
类型指针没有任何保障,只有在确保代码逻辑正确且不会出问题时再去考虑使用。
发布于 2023-03-05 13:29・IP 属地澳大利亚