0

译|There Are No Reference Types in Go

 2 years ago
source link: https://www.cyningsun.com/08-23-2021/there-are-no-reference-types-in-go-cn.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

译|There Are No Reference Types in Go

有一天,我用谷歌搜索一个 Go 问题,谷歌将我引导到 Go FAQ 页面。问题解决后,我阅读了整个 FAQ。

这是一次很棒的阅读,我从文章中学到了很多。但我注意到一个问题, 为什么数组是值,而 map、slice 和 channel 是引用?答复如下:

此话题历史久远。在早期,map 和 channel 都是语法指针,不能声明和使用非指针实例。此外,我们在竭尽全力探索数组如何工作。最终,我们认为指针和值的严格分离使语言更难使用。将这些类型更改为对关联的共享数据结构的引用,就解决了这些问题。改变给语言增加了一些令人遗憾的复杂性,但却对可用性产生了很大的影响:Go 一经推出,就成为了一种更高效、更舒服的语言。

令我惊讶的是,Go 官方文档仍在使用“引用类型”的概念,因为自 2013 年 4 月 3 日以来,“引用类型”的概念已从 Go 规范中完全删除。现在 Go 规范中有 10 个“引用”词,没有一个代表“引用类型”的概念。

另一个惊喜是这句话:

…指针和值的严格分离使该语言更难使用。…

此答复将指针和值视为两个不兼容的概念。但是,Go 规范将指针视为特殊值,指针被称为“指针值”。值只是类型的实例。显然,Go 规范中“指针”一词的定义很好。我认为如果使用“指针值和非指针值”会更好。

所以,我认为此答复给 Go 社区带来了很多困惑。它与当前 Go 规范冲突,并且打破了概念的一致性。

谈回第一个惊喜,我认为称呼 map/slice/channel 值为引用值完全没有必要。不仅因为 “reference” 这个词在编程世界中被滥用了,还因为 map/slice/channel 值只是普通的正常值

以下是 map/slice/channel 类型的内部声明:

Type Family Type Declaration map struct {
m *internalHashtable
} channel struct {
c *internalChannel
} slice struct {
array *internalArray
len int
cap int
}

请注意,上面的声明可能不完全与官方或非官方的 Go 实现中的声明相同。Go 实现可以直接使用指针表示 map 和 channel 的值,但 Go 规范/编译器永远不会将它们视为指针。因此,你可以放心的将 map/slice/channel 类型视为上面声明的指针包装类型,而不会有任何问题。

从上面的声明,很容易得出结论:map/slice/channel 只是包含一个非导出指针字段的结构类型。将它们称为引用类型是完全没有必要的。

Map 和 slice 类型与一般结构类型确实有一个区别。与一般结构类型不同,对于 map 或 slice 类型 T,T{} 不是 T 的零值。但这不是将 map 或 slice 类型拆分为新的引用类型类别的好理由。

通过理解 Go 的以下两个规则:

  • map/slice/channel 值只是普通的指针包装结构的值
  • 所有赋值,包括参数传递等,都是浅值复制(指针指向的值不会被复制)

Gopher 应该清楚地理解赋值中的 dest 和 source map/slice/channel 值将共享被包装的指针所指向的同一底层数据。

概念是用来帮助程序员理解语言的机制,而不是混淆他们。值、指针值和非指针值的概念足以让 Gopher 理解 Go。

我希望 Go 文档不会破坏概念定义的一致性。

原文:https://www.tapirgames.com/blog/golang-has-no-reference-values

本文作者:cyningsun
本文地址https://www.cyningsun.com/08-23-2021/there-are-no-reference-types-in-go-cn.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK