num
变量,值为 5,类型为 int
。取了其对于的指针地址后,试图强制转换为 *float32
,结果失败...unsafe
标准库来解决。它是一个神奇的包,在官方的诠释中,有如下概述:unsafe.Pointer
。它表示任意类型且可寻址的指针值,可以在不同的指针类型之间进行转换(类似 C 语言的 void * 的用途)unsafe.Pointer
的特性对该指针变量进行了修改,就可以完成任意类型(*T)的指针转换n.i
值:i
为第一个成员变量。因此不需要进行偏移量计算,直接取出指针后转换为 Pointer
,再强制转换为字符串类型的指针值即可n.j
值:j
为第二个成员变量。需要进行偏移量计算,才可以对其内存地址进行修改。在进行了偏移运算后,当前地址已经指向第二个成员变量。接着重复转换赋值即可uintptr
是 Go 的内置类型。返回无符号整数,可存储一个完整的地址。后续常用于指针运算ArbitraryType
表示任意类型,并非定义的 int
。它实际作用是一个占位符Pointer
的第三、第四点特性。这时候就已经可以对变量进行操作了 😄uintptr
类型是不能存储在临时变量中的。因为从 GC 的角度来看,uintptr
类型的临时变量只是一个无符号整数,并不知道它是一个指针地址ptr
这个临时变量是可能被垃圾回收掉的,那么接下来的内存操作,岂不成迷?unsafe.Pointer
可以让你的变量在不同的指针类型转来转去,也就是表示为任意可寻址的指针类型。第二是 uintptr
常用于与 unsafe.Pointer
打配合,用于做指针运算,巧妙地很unsafe
标准库,它并不安全。虽然它常常能让你眼前一亮 👌