指针运算
uintptr是整型,可以足够保存指针的值得范围,在32平台下为4字节,在64位平台下是8字节,它和unsafe.Pointer可相互转换。 uintptr和unsafe.Pointer的区别就是:unsafe.Pointer只是单纯的通用指针类型,用于转换不同类型指针,它不可以参与指针运算;而uintptr是可用于指针运算的。
// TestUintptr1: pointer_test.go:54: a.addr=0xc00000a368, b.addr=0xc00000a368, *b=100 // TestUintptr1: pointer_test.go:56: buintptr=0xc00000a368 func TestUintptr1(t *testing.T) { var a int a = 100 b := (*int)(unsafe.Pointer(&a)) t.Logf("a.addr=%p, b.addr=%p, *b=%d", &a, b, *b) buintptr := uintptr(unsafe.Pointer(&a)) t.Logf("buintptr=0x%x", buintptr) } // TestUintptr2: pointer_test.go:65: a0.addr=0xc00000a370, a1.addr=0xc00000a378 // TestUintptr2: pointer_test.go:67: auintptr=0xc00000a370 // TestUintptr2: pointer_test.go:71: a1pointer=0xc00000a378, a1=2 func TestUintptr2(t *testing.T) { var a [2]int a[0] = 1 a[1] = 2 t.Logf("a0.addr=%p, a1.addr=%p", &a[0], &a[1]) auintptr := uintptr(unsafe.Pointer(&a)) t.Logf("auintptr=0x%x", auintptr) a1uintptr := auintptr + unsafe.Sizeof(&a) a1pointer := unsafe.Pointer(a1uintptr) a1 := *(*int)(a1pointer) t.Logf("a1pointer=%p, a1=%d", a1pointer, a1) }
获取到auintptr表示a数组的首地址,把它加上一个指针长度,就会得到a数组下一个元素。Go显然是不想让你进行指针运算的,否则也不会这么麻烦,这也符合工程语言的初衷。
一个没有高级趣味的人。
email:hushui502@gmail.com