Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency 通道是否通过引用隐式传递_Concurrency_Go_Channels_Pass By Reference - Fatal编程技术网

Concurrency 通道是否通过引用隐式传递

Concurrency 通道是否通过引用隐式传递,concurrency,go,channels,pass-by-reference,Concurrency,Go,Channels,Pass By Reference,go tour的频道示例如下: 主程序包 输入“fmt” 函数和(a[]整数,c chan整数){ 总和:=0 对于u,v:=范围a{ 总和+=v } c你可以说是的,但是说“信道c在求和函数中被修改”并不是真正正确的术语。信道发送和接收并不是真正的修改 请注意,切片和贴图的行为方式类似,有关详细信息,请参见 另外,“通过引用传递”意味着可以在sum中对c赋值,这将在sum之外改变它的值(相对于它的基础数据),情况并非如此。通道变量是引用,但这取决于您对“引用”的定义。永远不要提及引用类型 su

go tour的频道示例如下:

主程序包
输入“fmt”
函数和(a[]整数,c chan整数){
总和:=0
对于u,v:=范围a{
总和+=v
}

c你可以说是的,但是说“信道c在求和函数中被修改”并不是真正正确的术语。信道发送和接收并不是真正的修改

请注意,切片和贴图的行为方式类似,有关详细信息,请参见


另外,“通过引用传递”意味着可以在
sum
中对
c
赋值,这将在sum之外改变它的值(相对于它的基础数据),情况并非如此。

通道变量是引用,但这取决于您对“引用”的定义。永远不要提及引用类型

sum
函数中未“修改”任何通道(变量)。发送到通道会更改其状态

换句话说,是的,通道被实现为指向某个运行时结构的指针

编辑:上面这句话的意思是:“注意,对于引用语义来说,这并不是绝对必要的。”,即“not”一词消失了。很抱歉,任何最终造成的混乱。

从技术上讲,它们是被复制的,因为当您使用
make
时,您在堆上分配了一些东西,因此从技术上讲,它在幕后是一个指针。但是指针类型没有公开,因此可以将其视为引用类型

编辑:从规范:

内置函数make采用类型T,该类型必须是片、映射或通道类型,后面可选地跟有特定于类型的表达式列表。它返回类型T(而不是*T)的值。内存初始化如初始值部分所述

通道必须先初始化,然后才能使用。Make执行此操作,以便将其用作引用类型

这基本上意味着,您可以将其传递到函数中,并对其进行写入或读取。一般的经验法则是,如果使用
make
new
&
,您可以将其传递到另一个函数,而无需复制底层数据

因此,以下是“参考”类型:

  • 切片
  • 地图
  • 渠道
  • 指针
  • 功能
传递到函数中时,仅复制数据类型(数字、布尔值和结构等)。字符串是特殊的,因为它们是不可变的,但不是按值传递的。这意味着以下内容无法按预期工作:

type A struct {
    b int
}
func f(a A) {
    a.b = 3
}
func main() {
    s := A{}
    f(s)
    println(s.b) // prints 0
}

Go中的所有内容都是通过值传递和分配的。某些内置类型,包括通道类型和映射类型,表现为指向某些隐藏内部结构的不透明指针。可以通过对通道或映射的操作来修改该内部结构。它们开始时为
nil
,类似于
nil
poiINTER.

是的,Go中的引用类型是
slice
map
channel
。传递这些类型时,您正在复制引用。(字符串也作为引用类型实现,尽管它们是不可变的。)@tjameson:make并不意味着堆分配,而slice实际上是作为一个结构实现的,并在传递时被复制。@斜视-对。
array
,我的意思是
make([]int,5)
,但我刚刚意识到这在技术上更像是一个切片。我的不好。@jml-回顾规范,我想在技术上不是这样的。我会编辑。指针不是真正的引用类型,它们是碰巧用作引用的值类型。
slice
的行为不像
map
chan
d中的“不透明指针”o、 如果使用参数
a[]string
调用的函数将其更改为
a=append(a,x)
,则调用者将看不到长度的更改。对预先存在的索引的更改是可见的(除非在同一个func中它前面的
append
导致重新分配)。
type A struct {
    b int
}
func f(a A) {
    a.b = 3
}
func main() {
    s := A{}
    f(s)
    println(s.b) // prints 0
}