此代码的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
答案 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)
在你的情况下,你附加一个切片(指针)而不是切片的值。要获得所需的结果,您必须在每次迭代中声明一个新切片,并将新切片附加到切片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]]
}
答案 2 :(得分:0)
问题在于,您追加到slice2
的内容是引用到slice
,而不是slice
在调用时包含的值。
这意味着最后,slice2
包含指向同一切片的两个指针。对slice
变量的任何更改都会反映到slice2
,反之亦然:它们指向内存中的相同位置。
作为证明,只需:
slice2[0][1] = 2
fmt.Println(slice2)
fmt.Println(slice)
你会得到:
[[1 2] [1 2]]
[1 2]