28.1 unsafe 包

在unsafe包中,只提供了3个函数,两个类型。
func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr
type ArbitraryType int
type Pointer *ArbitraryType

就这么少的量,却有着超级强悍的功能。一般我们在C语言中通过指针,在知道变量在内存中占用的字节数情况下,就可以通过指针加偏移量的操作,直接在地址中,修改,访问变量的值。在Go 语言中不支持指针运算,那怎么办呢?其实通过unsafe包,我们可以完成类似的操作。

ArbitraryType 是以int为基础定义的一个新类型,但是Go 语言unsafe包中,对ArbitraryType赋予了特殊的意义,通常,我们把interface{}看作是任意类型,那么ArbitraryType这个类型,在Go 语言系统中,比interface{}还要随意。

Pointer 是ArbitraryType指针类型为基础的新类型,在Go 语言系统中,可以把Pointer类型,理解成任何指针的亲爹。

Go 语言的指针类型长度与int类型长度,在内存中占用的字节数是一样的。ArbitraryType类型的变量也可以是指针。

func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr

通过分析发现,这三个函数的参数均是ArbitraryType类型。

  1. Alignof返回变量对齐字节数量
  2. Offsetof返回变量指定属性的偏移量,所以如果变量是一个struct类型,不能直接将这个struct类型的变量当作参数,只能将这个struct类型变量的属性当作参数。
  3. Sizeof 返回变量在内存中占用的字节数,切记,如果是slice,则不会返回这个slice在内存中的实际占用长度。

unsafe中,通过ArbitraryType 、Pointer 这两个类型,可以将其他类型都转换过来,然后通过这三个函数,分别能取长度,偏移量,对齐字节数,就可以在内存地址映射中,来回游走。