会触发

我们用下面代码的方法就可以不触发内存拷贝,让切片指向字符串底层字节数组的地址了

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

}

可以看到,直接转换成字节数组,其内部指向的字节数组地址是发生了内存复制的