如果 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 函数的调用外,并没有什么任何特殊之处。


分享到:


相關文章: