unsafe.Pointer/uintptr
- unsafe.Pointer只是单纯的通用指针类型,任何类型的指针值都可以转换为 Pointer,Pointer 也可以转换为任何类型的指针值。但它不可以参与指针运算
- uintptr 无符号整数uint64,是Go 的内置类型,用于指针运算的
- unsafe.Pointer 可以和 uintptr 进行相互转换
注意,
- GC 并不把 uintptr 当指针,也就是说 uintptr 无法持有对象, 如果目标对象经过uintptr转换之后没有其它的引用了,会被GC(不过由于GC延迟机制,不再被使用的内存块的回收时间 是 不确定的)
- 但如果是unsafe.Pointer 指向了一个对象,那么 go 的 GC 会知道有这个对象,并不会释放这个对象的内存。
string 和 []byte 零拷贝转换
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
type StringHeader struct {
Data uintptr
Len int
}
对比string和slice的数据结构,通过共享底层 []byte 数组、然后浅拷贝构造header,就可以实现零拷贝转换
func string2bytes(s string) []byte {
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{
Data: stringHeader.Data,
Len: stringHeader.Len,
Cap: stringHeader.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
}
func bytes2string(b []byte) string {
sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{
Data: sliceHeader.Data,
Len: sliceHeader.Len,
}
return *(*string)(unsafe.Pointer(&sh))
}

浙公网安备 33010602011771号