如果 map 不是引用變量,那是什麼?

之前也翻譯過兩篇 Dave 大神的文章,可以看這裡《 》和《 》,很多人問他是誰?給大家簡單介紹下:

他是 Go 語言的開源貢獻者和項目成員,技術界中受人尊敬的代言人,在軟件設計、性能和 Go 語言等各種主題上發表演講。在油管上可以看到很多他演講的視頻,反正就是很牛逼!

博客地址:https://dave.cheney.net/

原文如下:


在上一篇文章中,給大家說明了 Go 語言的 map 不是引用變量,也不會通過引用傳遞。這留了一個問題,如果 map 不是引用變量,那它們是什麼?

不急,先看答案:

map 是指向 runtime.hmap 結構體的指針。

如果你不滿意這種解釋,接著往下看。

map 值的類型是什麼?

當你寫下如下代碼

編譯器會自動去調用 runtime.makemap,看下方法簽名:

正如你看到的那樣,從 runtime.makemap 返回的值的類型是指向 runtime.hmap 結構體的指針。從平常的代碼中看不出這一點,但我們可以確認的是 map 值的大小與 uintptr 相同。

如果 map 是指針,那是不是應該這樣表示 *map[key]value ?

這是個好問題,如果 map 是指針的話,為什麼表達式 make(map[int]int) 返回的是類型為 map[int]int 的值,不是應該返回 *map[int]int 嗎?

可以說,將類型從 *map[int]int 重命名為 map[int]int 雖然有點混亂,因為類型看起來不像指針,但相較於指針值不能解引用,混亂程度會好點。

總結

map 與 channel 一樣,都是 runtime 類型的指針, 這與 slice 不同。正如你在上面看到的那樣,map 是指向 runtime.hmap 結構體的指針。

map 與 Go 語言中其他類型的指針值具有相同的指針語義,除了編譯器會將 map 重寫為對 runtime/map.go 函數的調用外,並沒有什麼任何特殊之處。


分享到:


相關文章: