go语言多重复值
例题思考
func main() {arr := make([]int, 5)fmt.Println(arr)i := 1i, arr[i] = 2, 3fmt.Println(i)fmt.Println(arr)
}// [0 0 0 0 0]
// 2
// [0 3 0 0 0]
正确的执行顺序
实际上,Go语言的多重赋值机制比最初描述的要更精细。正确的执行顺序是:
- 先计算所有右侧表达式的值(从左到右)
- 然后从左到右赋值给左侧变量
对于i, arr[i] = 2, 3
的具体执行步骤:
- 计算右侧表达式:
- 第一个值:2
- 第二个值:3
此时会先确定 arr[i] 中的 i 的当前值(因为这是表达式求值阶段)
- 赋值阶段:
- 第一个赋值:
i = 2
(此时i被更新为2) - 第二个赋值:
arr[i] = 3
(这里的i使用的是原始值,不是刚赋值的2)
- 第一个赋值:
关键点说明
表达式求值阶段:在计算右侧所有表达式时,会固定所有需要使用的索引和地址
赋值阶段:按照从左到右的顺序进行赋值,但使用的索引是在表达式求值阶段确定的
Go语言规范明确指出:
- 在赋值语句中,右侧的表达式会先全部被求值
- 然后按从左到右的顺序进行赋值
- 当表达式中有索引时(如
arr[i]
),索引值是在表达式求值阶段确定的
更复杂的例子
func main() {i := 1arr := []int{0, 0, 0}i, arr[i], arr[i-1] = i+1, i+2, i+3fmt.Println(arr)
}
// [4 3 0]
执行过程:
-
求值右侧:
i+1 = 2
i+2 = 3
i+3 = 4
- 确定索引:
arr[i]→arr[1], arr[i-1]→arr[0]
-
赋值:
i = 2
arr[1] = 3
arr[0] = 4
结果:i=2, arr=[4,3,0]
总结
在表达式求值阶段就已经确定了arr[i]
中的i值,不会受到后续i赋值的影响。