会触发
我们用下面代码的方法就可以不触发内存拷贝,让切片指向字符串底层字节数组的地址了
package main
import (
"fmt"
"reflect"
"unsafe"
)
func str2BytesOld(s string) []byte {
// 获取字符串底层结构体头部指针
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
//转换成通用指针类型,然后强制转换成指向字节切片的指针,再取出这个指针指向切片的内容,存入变量bytes中,返回这个变量
bytes := *(*[]byte)(unsafe.Pointer(ptr))
return bytes
}
func str2Bytes(s string) []byte {
//获取指向底层字节数组的指针
ptr := unsafe.StringData(s)
// unsafe.Slice用于从数组指针创建切片
return unsafe.Slice(ptr, len(s))
}
func main() {
a := "helloworl123"
bytes := str2Bytes(a)
bytes2 := str2BytesOld(a)
bytes3 := []byte(a)
// 打印底层数据的地址
fmt.Printf("bytes data address: %x\n", unsafe.SliceData(bytes))
fmt.Printf("bytes2 data address: %x\n", unsafe.SliceData(bytes2))
fmt.Printf("bytes3 data address: %x\n", unsafe.SliceData(bytes3))
}
可以看到,直接转换成字节数组,其内部指向的字节数组地址是发生了内存复制的