August 2021
Beginner to intermediate
450 pages
6h 1m
Chinese
很多指针类型都写作*T,意思是“一个指向T类型变量的指针”。unsafe.Pointer类型是一种特殊类型的指针,它可以存储任何变量的地址。当然,我们无法间接地通过一个unsafe.Pointer变量来使用*p,因为我们不知道这个表达式的具体类型。和普通的指针一样,unsafe.Pointer类型的指针是可比较的并且可以和nil做比较,nil是指针类型的零值。
一个普通的指针*T可以转换为unsafe.Pointer类型的指针,另外一个unsafe.Pointer类型的指针也可以转换回普通指针,而且可以不必和原来的类型*T相同。例如,通过转换一个*float64类型的指针到*uint64类型,可以查看一下浮点类型变量的位模式:
也可以通过结果指针来更新位模式。这个对一个浮点类型的变量来说是无害的,但是通常使用unsafe.Pointer进行类型转换可以让我们将任意值写入内存中,并因此破坏了类型系统。
unsafe.Pointer类型也可以转换为uintptr类型,uintptr类型保存了指针所指向地址的数值,这就可以让我们对地址进行数值计算。(回忆一下第3章,uintptr类型是一个足够大的无符号整型,可以用来表示任何地址。)这种转换当然也可以反过来,但是这种从uintptr到unsafe.Pointer的转换也会破坏类型系统,因为并不是所有的数值都是合法的内存地址。
很多unsafe.Pointer类型的值都是从普通指针到原始内存地址以及再从内存地址到普通指针进行转换的中间值。下面的例子获取变量x的地址,然后加上其成员b的地址偏移量,并将结果转换为*int16指针类型,接着通过这个指针更新x.b的值。 ...