Go语言——String与Slice深度解析

Note: 他们都是struct类型的


String

type StringHeader struct {
    Data uintptr
    Len  int
}

Slice

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

把Slice转换为String的语法为

[]byte("string")
string([]byte{1,2,3})

注意:这种实现会有拷贝操作


如何避免拷贝操作呢?

答案是自己实现指针转换(也可用反射实现头部转换),省去复制数据部分,同时注意这种实现后底层的数据不能再更改了,不然容易引发错误

直接修改指针类型并构建相应头部

func String2Slice(s string) []byte {
    sp := *(*[2]uintptr)(unsafe.Pointer(&s))
    bp := [3]uintptr{sp[0], sp[1], sp[1]}
    return *(*[]byte)(unsafe.Pointer(&bp))
}

func BytesToString(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

使用反射机制获取到头部再进行转换

func Slice2String(b []byte) (s string) {
    pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
    pstring.Data = pbytes.Data
    pstring.Len = pbytes.Len
    return
}


func String2Slice(s string) (b []byte) {
    pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
    pbytes.Data = pstring.Data
    pbytes.Len = pstring.Len
    pbytes.Cap = pstring.Len
    return
}