unsafe.Pointer 和 uintptr

unsafe.go

type ArbitraryType int
type Pointer *ArbitraryType

unsafe.Pointer 就是指针,简单理解,指针是内存中的一个地址, 通过该地址,可以将内存中的数据取出来。


builtin.go

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

uintptr 是golang 内置类型, 实质是uint, 可以用来存放“指针的值", 即地址值


unsafe.Pointer 与 uintptr 有何区别呢?
前者可以用来寻址(将内存中的数据取出), 后者单纯是一个数值类型(可以存放地址值)


实例

通过一段代码来区分它们

package main

import (
	"fmt"
	"unsafe"
)

type Human struct {
	sex  bool
	age  uint8
	id  int
	name string
}

func main() {
	h := Human{
		true,
		30,
		1026,
		"hello",
	}
	fmt.Printf("%p\n", &h)
	fmt.Printf("%v\n", &h)  //&h 通过 %v 打印,还是会将其存放的变量值打印出来
	fmt.Printf("%v\n",  unsafe.Pointer(&h) ) // 转换为 “地址值”, 在通过%v打印的就是具体的地址值
	


	p2 := unsafe.Pointer(&h.id)


	//p3 := unsafe.Pointer(uintptr(p2) + unsafe.Sizeof(h.id))  //正确编译运行
	
	p3 := unsafe.Pointer(uintptr(p2) +  0x08  ) //正确编译运行, p2是指针,不能直接与数值做运算,需先转换为uintptr
	
	//p3 := unsafe.Pointer(p2 +  0x08  )   //不能正确编译: cannot convert 0x08 (untyped int constant 8) to unsafe.Pointer

	p31 := (*string)(p3)
	println(*p31)

}


输出结果:

0xc000026040
&{true 30 1026 hello}
0xc000026040
hello


代码分析:
具体参考代码中注释, 实际运行一遍