197 字
1 分钟
如何实现字符串和byte切片的零拷贝转换

这是一个非常精典的例子。实现字符串和 bytes 切片之间的转换,要求是 zero-copy。想一下,一般的做法,都需要遍历字符串或 bytes 切片,再挨个赋值。

完成这个任务,我们需要了解 slice 和 string 的底层数据结构:

type StringHeader struct {
Data uintptr
Len int
}
type SliceHeader struct {
Data uintptr
Len int
Cap int
}

上面是反射包下的结构体,路径:src/reflect/value.go。只需要共享底层 []byte 数组就可以实现 zero-copy

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))
}

代码比较简单,不作详细解释。通过构造 slice header 和 string header,来完成 string 和 byte slice 之间的转换。

如何实现字符串和byte切片的零拷贝转换
https://blog.zhequtao.com/posts/golang/go-questions/标准库/unsafe/如何实现字符串和byte切片的零拷贝转换/
作者
阿俊
发布于
2020-03-30
许可协议
CC BY-NC-SA 4.0

相关阅读