我对Go中的多个作业感到有点困惑,例如varA, varB = varC, varD
。
我的问题是,这样的操作是原子的(当然不是在HW层,而是从程序员的角度来看)?
就我个人而言,我希望它是原子的,所以这个表达式a, b = b, a
只是交换值。我在Go playground中尝试了它,是的,它的确如此。
另一方面,Golang specs州:
转让分两个阶段进行。首先,左侧的索引表达式和指针间接操作(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序进行评估。 其次,分配按从左到右的顺序进行。
我理解为a
被赋予b
的值,然后b
被赋予a
的值(现在为b
),最后,a
和b
都等于b
的原始值。
规格是错误的还是我误解了?
答案 0 :(得分:5)
你误解了它,这不是你误解的第二部分。
规范说:
首先,左边的索引表达式和指针间接操作(包括选择器中的隐式指针间接)的操作数和右边的表达式都按照通常的顺序评估。
这里评估意味着所有表达式,包括变量都是......,好吧,被评估为值,并且该值在那时是固定的。所以在a,b = b,a
中,在第一部分中,lhs表达式a,b
得到了解析,rhs表达式b,a
被评估为5,3
(假设a,b:=3,5
,当然);在第二部分,作业发生了,变成了a = 5; b = 3
。
使用defer和goroutine时,评估是一样的。这就是为什么以下代码打印5。
func T() {
x := 5
defer func(i int) {
fmt.Println(i)
}(x)
x = 3
}