Golang切片附加内置函数返回值

时间:2017-02-20 19:00:18

标签: go slice

此代码的slice2的返回值为[[1 1] [1 1]] 这让我感到困惑,因为我期待[[0 0] [1 1]] 我无法弄清楚为什么返回[[1 1] [1 1]]而不是[[0 0] [1 1]]。
如果有人可以解释,我将不胜感激。感谢。

slice := []int{0, 0}
slice2 := [][]int{}

for i := range slice {
    slice[0] = i
    slice[1] = i
    slice2 = append(slice2, slice)
}
fmt.Println(slice2)

您可以查看此链接中的代码 play.golang.org

3 个答案:

答案 0 :(得分:1)

当您对切片进行范围调整时,它不会为您提供切片的值,而是为您提供索引。此for循环等效于for i:=0; i < len(slice); i++ {}。因此,当它通过迭代时,slice中的两个值都是1,并且您已将其附加到slice2两次。

如果您想要切片的值,则需要执行for i, v := range slice {},这将为您提供索引和值。如果您不想要索引,可以使用_代替i

另请注意,像这样附加slice两次会附加相同的精确切片,因为切片在堆上被指定为指针,因此它是指向切片的指针。因此slice2[0] == slice2[1]因为它是完全相同的切片。

答案 1 :(得分:1)

  

A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).

在你的情况下,你附加一个切片(指针)而不是切片的值。要获得所需的结果,您必须在每次迭代中声明一个新切片,并将新切片附加到切片2。

func main() {
    slice := []int{0, 0}
    slice2 := [][]int{}

    for i := range slice {
        ns := []int{0, 0}
        ns[0] = i
        ns[1] = i
        slice2 = append(slice2, ns)
    }
    fmt.Println(slice2) // Outputs: [[0 0] [1 1]]
}

Playground

答案 2 :(得分:0)

问题在于,您追加到slice2的内容是引用slice,而不是slice在调用时包含的值。

这意味着最后,slice2包含指向同一切片的两个指针。对slice变量的任何更改都会反映到slice2,反之亦然:它们指向内存中的相同位置。

作为证明,只需:

slice2[0][1] = 2
fmt.Println(slice2)
fmt.Println(slice)

你会得到:

[[1 2] [1 2]]
[1 2]