Arrays 更改数组元素无效

Arrays 更改数组元素无效,arrays,go,Arrays,Go,编译器或我对Go的理解有问题。我有一个奇怪的bug,并把它简化为一个简单的例子。由于某些原因,我无法在循环中直接更改数组 var nums [2]int for i, v := range nums { if i == 0 { nums[i+1]++ } else { fmt.Print(v) } } 这将增加nums[1],然后打印它。所以它应该打印1,但它打印0。当您在表

编译器或我对Go的理解有问题。我有一个奇怪的bug,并把它简化为一个简单的例子。由于某些原因,我无法在循环中直接更改数组

    var nums [2]int
    for i, v := range nums {
        if i == 0 {
            nums[i+1]++
        } else {
            fmt.Print(v)
        }
    }

这将增加nums[1],然后打印它。所以它应该打印1,但它打印0。

当您在表达式中使用数组时,您会得到它的值,即数组的完整新副本。这包括在循环的范围表达式中使用数组。因此,当您打印v时,您正在打印副本,但实际的nums数组已更改

在片上而不是阵列上循环可以实现您所期望的:

    var nums [2]int
    for i, v := range nums[:] {
        if i == 0 {
            nums[i+1]++
        } else {
            fmt.Print(v)
        }
    }

该范围创建数组及其值的副本,以便可以对其进行迭代

如果您计划在迭代过程中对一个数组或其中的一个片段进行变异,最好直接引用该数组/片段,因为v值将是数组的一个副本,而在代码中是数组的一个旧副本

因此,请尝试以下方法:

var nums [2]int
for i := range nums {
    if i == 0 {
        nums[i+1]++
    } else {
        fmt.Print(nums[i])
    }
}

经验法则:在围棋中使用数组可能是错误的。@Volker你错了-不存在这样的规则这就是为什么规则在你的拇指上!非常严肃地说,数组对于静态定义来说是不错的—请参阅go的time pkg对于一周中的几天—但对于可变值,最好使用切片。如果你需要一定的尺寸,用make预先分配切片。