pointers - Golang 中的 *uint 和 uintptr 有什么区别?

标签 pointers go

根据Golang tour ,我们提供了以下整数类型:

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

理论上,这意味着我们还可以拥有指向所有这些类型的指针,如下所示:

*int  *int8  *int16  *int32  *int64
*uint *uint8 *uint16 *uint32 *uint64 *uintptr

如果是这种情况,那么我们已经有了一个指向 *uint 形式的 uint 的指针。这将使 uintptr 变得多余。 official documentation并没有说明这一点:

uintptr is an integer type that is large enough to hold the bit pattern of any pointer.

据我了解,这意味着 uint 的位宽是在编译时根据目标体系结构(通常是 32 位或 64 位)确定的。指针宽度也应该缩放到目标体系结构似乎是合乎逻辑的(即:32 位 *uint 指向 32 位 uint)。 Golang 也是这样吗?

另一个想法是,也许添加 uintptr 是为了使在进行多重间接寻址时语法不那么困惑(IE:foo *uinptr vs foo **uint)?

我最后的想法是,也许指针和整数在 Golang 中是不兼容的数据类型。这将是相当令人沮丧的,因为硬件本身并不区分它们。例如,“分支到此地址”指令可以使用来自刚刚在“添加此值”指令中使用的同一寄存器的相同数据。

uintptr 的真正意义是什么(双关语)?

最佳答案

简短的回答是“永远不要使用uintptr”。 😀

长的答案是,uintptr可以绕过类型系统并允许Go实现者在Go中编写Go运行时库,包括垃圾收集系统,并调用C可调用代码包括使用 C 指针的系统调用,这些调用根本不由 Go 处理。

如果您充当实现者(例如,提供对新操作系统上的系统调用的访问),您将需要 uintptr。您还需要了解使用它所需的所有特殊魔法,例如,如果操作系统要对操作系统级线程执行堆栈式操作,则将 goroutine 锁定到操作系统级线程。 (如果您将其与 Go 指针一起使用,您可能还需要告诉编译器不要移动您的 goroutine 堆栈,这是通过特殊的编译时指令完成的。)

编辑:如kostix notes in a comment ,运行时系统将 unsafe.Pointer 视为对对象的引用,这使对象在 GC 时保持事件状态。它uintptr视为这样的引用。 (也就是说,unsafe.Pointer 具有指针类型,而 uintptr 具有整数类型。)另请参阅 documentation for the unsafe package .

关于pointers - Golang 中的 *uint 和 uintptr 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59042646/

相关文章:

Golang 如何将网站部署到主机

C 指针 - 很好的教程

c++ - QSharedPointer::创建()

c - 如何定义一个指针类型的结构体?

python - ctypes 将指针传递给结构中的字段

go - package语句与.go文件目录的关系

go - 将go命令作为gradle任务运行

sql - 后端是否应该在 SQL 查询之前执行一致性检查?

c - C中的函数后指针不返回

go - 无法将 JSON 解码为结构