当我遍历幻灯片上的 for 循环时(下面的代码),我得到了输出输出:
0A,1M,2C,
代码:
x := []string{"A", "B", "C"}
for i, s := range x {
print(i, s, ",")
x[i+1] = "M"
x = append(x, "Z")
x[i+1] = "Z"
}
为什么输出完全一样,不是
0A, 1Z, 2Z
?
阅读文档,我看到切片是通过指向它所基于的数组的指针传递给函数的。
slice也是通过指针传递给for循环的吗? (在文档中找不到原因)
如果是这样,我猜测为什么输出恰好是 0A、1M、2C,- 因为,最初,切片是通过指针传递给循环的,当切片的容量在循环的第一次迭代中加倍时, print(i, s) 值仍然基于基本数组打印。这是真的吗?
range
只检查一次x
的大小。append
是添加到数组的末尾,但范围尊重原始结束。让我们用更多的调试来标记循环。
x := []string{"A", "B", "C"}
for i, s := range x {
fmt.Printf("Start: i=%v s=%v x=%v\n", i, s, x)
x[i+1] = "M"
fmt.Printf("After x[i+1] = \"M\": i=%v s=%v x=%v\n", i, s, x)
x = append(x, "Z")
fmt.Printf("After Append: i=%v s=%v x=%v\n", i, s, x)
x[i+1] = "Z"
fmt.Printf("After x[i+1] = \"Z\": i=%v s=%v x=%v\n\n", i, s, x)
}
结果...
Start: i=0 s=A x=[A B C]
After x[i+1] = "M": i=0 s=A x=[A M C]
After Append: i=0 s=A x=[A M C Z]
After x[i+1] = "Z": i=0 s=A x=[A Z C Z]
Start: i=1 s=M x=[A Z C Z]
After x[i+1] = "M": i=1 s=M x=[A Z M Z]
After Append: i=1 s=M x=[A Z M Z Z]
After x[i+1] = "Z": i=1 s=M x=[A Z Z Z Z]
Start: i=2 s=C x=[A Z Z Z Z]
After x[i+1] = "M": i=2 s=C x=[A Z Z M Z]
After Append: i=2 s=C x=[A Z Z M Z Z]
After x[i+1] = "Z": i=2 s=C x=[A Z Z Z Z Z]
如您所见,x 不断增长,这就是
x = append(x, "Z")
所做的。否则你正在写 M 然后用 Z 覆盖它。