簡體   English   中英

為什么 Golang string.Builder String() 可以在沒有 reflect.StringHeader 的情況下將 []byte 轉換為 slice?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM