亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Golang string.Builder String() 可以在沒有

為什么 Golang string.Builder String() 可以在沒有

Go
陪伴而非守候 2022-10-24 15:37:04
Go 的 strings 包定義了一個 Builder 類型,它有一個 String() 方法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}))}
查看完整描述

1 回答

?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

讓我們分解一下。

表達式&buf是指向切片頭的指針。指向切片的指針是指向切片頭的指針。

該表達式(unsafe.Pointer(&buf)是從切片頭指針到unsafe.Pointer. unsafe.Pointer 類型有一個神奇的屬性——它可以與任何其他指針類型相互轉換。

表達式是(*string)(unsafe.Pointer(&buf))從切片頭指針到字符串頭指針的轉換。指向字符串的指針是指向標頭的指針。

此時,我們有一個字符串頭指針,它實際上指向一個切片頭。乍一看,這似乎很糟糕,但一切都很好。字符串頭的內存布局是切片頭的內存布局的前綴。

該表達式*(*string)(unsafe.Pointer(&buf))取消引用字符串頭指針以獲取字符串。此操作將數據和長度字段從切片標頭復制到字符串標頭。

如果對切片頭字段重新排序而沒有對字符串頭字段進行相應更改,則此代碼將中斷,但這永遠不會發生。


查看完整回答
反對 回復 2022-10-24
  • 1 回答
  • 0 關注
  • 111 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號