golang [N]byte、string和[]byte
?字节数组,占用一块定长连续的内存,可读写。非0大小数组的长度不得超过2GB
字串本质是逻辑上只读的字节数组,零值是""而不是 nil。src/runtime/string.go 中字串结构定义如下: type stringStruct struct { str unsafe.Pointer //一个指针 len int //固定长度 } 零值""对应的底层结构体的值是: 指针是nil,len是0;做列几个注意点:
func main() { str1 := "" str2 := "1234" str3 := str1 str4 := "12" + "" + "34" str5 := fmt.Sprint("1234") str6 := strings.Join([]string{"12","34"},"") str1str := *(*stringStruct)(unsafe.Pointer(&str1)) str2str := *(*stringStruct)(unsafe.Pointer(&str2)) str3str := *(*stringStruct)(unsafe.Pointer(&str3)) str4str := *(*stringStruct)(unsafe.Pointer(&str4)) str5str := *(*stringStruct)(unsafe.Pointer(&str5)) str6str := *(*stringStruct)(unsafe.Pointer(&str6)) fmt.Println(str1str,str2str,str3str,str4str,str5str,str6str) }
?[]byte的底层数据结构,src/runtime/slice.go中定义如下: type slice struct { array unsafe.Pointer len int cap int } 和string不一样的地方是,多了个cap,最大可用的长度就是说len的可变是有限制的,实际也算个空间换时间呗。
(1)[N]byte 和 string,把string理解成[N]byte的只读版好了,但是两个不能直接转换可以用for循环一个一个byte复制,或者用指针魔法: func main() { str1 := "1234" arr1 := *(*[4]byte)((*stringStruct)(unsafe.Pointer(&str1)).str) fmt.Println(arr1) } [N]byte转string魔法? 就是把string看成stringStruct,初始化一下就行。 (2)[N]byte和[]byte转换,和string差不多吧。 (3)string 和?[]byte 这两可以直接强制类型转换。两个底层结构体很像,然后一个是只读,一个是可写,转换涉及到内存copy,有些开销。 func main() { arr := []byte{‘1‘,‘2‘,‘3‘,‘4‘} str2 := string(arr) str := fmt.Sprint("1234") arr2 := []byte(str) arrp := *(*unsafe.Pointer)(unsafe.Pointer(&arr)) str2p := *(*unsafe.Pointer)(unsafe.Pointer(&str2)) strp := *(*unsafe.Pointer)(unsafe.Pointer(&str)) arr2p := *(*unsafe.Pointer)(unsafe.Pointer(&arr2)) fmt.Println(arrp,str2p,strp,arr2p) } 原地转换黑魔法 func stringtoslicebyte(s string) []byte { sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) bh := reflect.SliceHeader{ Data: sh.Data,Len: sh.Len,Cap: sh.Len,} return *(*[]byte)(unsafe.Pointer(&bh)) } func slicebytetostring(b []byte) string { bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) sh := reflect.StringHeader{ Data: bh.Data,Len: bh.Len,} return *(*string)(unsafe.Pointer(&sh)) } ? 相关链接?golang string和[]byte的对比 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |