【发布时间】:2021-01-14 10:27:16
【问题描述】:
根据Go: reference types as arguments 中的响应和 cmets,Go 似乎没有“官方”称为“引用类型”的类型。
然而,有些类型实际上持有指向底层数据的指针,这允许有效地将这些类型的值作为函数参数传递,而无需获取指向它们的指针。当这样的值作为函数参数传递时,没有(或像切片一样很少)复制底层数据,因此如果程序员获取指向类型的指针并传递它,则没有(或很少)效率增益指针作为函数参数而不是值。
根据the accepted answer,这些类型是slices、maps和channels。
Effective Go 官方文档describes Slices 为:
切片包含对底层数组的引用,如果将一个切片分配给另一个切片,则两者都引用同一个数组。如果一个函数接受一个切片参数,它对切片元素所做的更改将对调用者可见,类似于传递一个指向底层数组的指针。
Maps 为:
与切片一样,映射包含对底层数据结构的引用。如果您将地图传递给更改地图内容的函数,则更改将在调用者中可见。
和Channels 为:
像地图一样,通道是用 make 分配的,结果值充当对底层数据结构的引用。
无论出于何种原因,文档似乎都避免对这些类型使用“引用类型”一词,但在每种情况下仍然提到“引用”一词。
这些类型的特别之处还在于可以将nil 分配给这种类型的值,类似于指针类型(doc):
如果满足以下条件之一,则值
x可分配给T类型的变量(“x可分配给T”):
...
x是预声明的标识符nil,T是指针、函数、切片、映射、通道或接口类型。
在日常程序员的实践中,很重要了解、清楚地区分和清楚地传达作为函数参数传递时共享底层数据与不共享底层数据的类型或数据结构(但复制)基础数据。
在与其他程序员,尤其是初级程序员交谈时,能够将 slices、maps 和 channels 作为一个单独的组来引用是一种清晰的通信有助于确保程序中的数据安全并识别/预防与改变共享状态相关的危险。
这组类型一般怎么称呼?
【问题讨论】:
-
但正如您所写,“有些类型实际上包含指针”。这些类型仍然等价于 C 结构。
-
Go 的唯一引用类型是指针。切片、映射和通道被描述为“持有”或“充当”引用只是指它们是或包含底层类型定义中的指针。
-
github.com/go101/go101/wiki/… 揭示了这个“术语”主题的历史
标签: go