string与[]byte的直接转换是通过底层数据copy实现的,在数据量较大时存在一定的消耗,其实存在更高效的转换方式:利用底层指针之间的转换,没有额外的内存分配,性能大大提升。
要实现这个目的,必须对string和[]byte底层结构深入了解:
struct string {
uint8 *str;
int len;
}
struct []uint8 {
uint8 *array;
int len;
int cap;
}
string 可看做 [2]uintptr,而 [ ]byte 则是 [3]uintptr,这便于我们编写代码,无需额外定义结构类型。如此,str2bytes 只需构建 [3]uintptr{ptr, len, len},而 bytes2str 更简单,直接转换指针类型,忽略掉 cap 即可
package main
import (
"fmt"
"strings"
"unsafe"
)
func str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0], x[1], x[1]}
return *(*[]byte)(unsafe.Pointer(&h))
}
func bytes2str(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func main() {
s := strings.Repeat("abc", 3)
b := str2bytes(s)
s2 := bytes2str(b)
fmt.Println(b, s2)
}
网友评论