![](/img/trans.png)
[英]Convert byte to string using reflect.StringHeader still allocates new memory?
[英]Why Golang string.Builder String() can convert []byte to slice without a reflect.StringHeader?
Go 的字符串 package 定義了一個具有 String() 方法的 Builder 類型
func (b *Builder) String() string {
return *(*string)(unsafe.Pointer(&b.buf))
}
正如 reflect pacakge 所指出的,一個字節切片被定義為一個 SliceHeader 和一個由 header 的 Data 字段指向的關聯數據塊:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
並且 string 被定義為一個 StringHeader 和一個由 header 的 Data 字段指向的關聯數據塊
type StringHeader struct {
Data uintptr
Len int
}
SliceHeader 有 3 個字段(Data、Len 和 Cap)而 StringHeader 只有 2 個(Data 和 Len),那么如何像這樣直接將字節切片轉換為字符串呢?
*(*string)(unsafe.Pointer(&buf))
據我了解,我們應該編寫以下代碼:
func byte2str(b []byte) string {
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
return *(*string)(unsafe.Pointer(&reflect.StringHeader{Data: hdr.Data, Len: hdr.Len}))
}
讓我們分解一下。
表達式&buf
是指向切片 header 的指針。 指向切片的指針是指向切片 header 的指針。
表達式(unsafe.Pointer(&buf)
是從切片 header 指針到unsafe.Pointer
的轉換。unsafe.Pointer 類型具有神奇的神奇屬性——它可以與任何其他指針類型相互轉換。
表達式是(*string)(unsafe.Pointer(&buf))
是從切片 header 指針到字符串 header 指針的轉換(指向字符串的指針是指向標頭的指針)。
表達式*(*string)(unsafe.Pointer(&buf))
取消引用字符串 header 指針以獲取字符串。
這一切都有效,因為字符串 header 的 memory 布局是 memory 布局 Z09749FB9953446F0DEF31 切片的前綴。 字符串 header 指針的最終取消引用僅復制兩個字符串 header 字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.