Go语言 如果一个切片在循环中增加了,那么如何迭代该切片呢?

gk7wooem  于 2023-04-09  发布在  Go
关注(0)|答案(1)|浏览(111)

当我在幻灯片上迭代for循环时(代码如下),我得到输出Output: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
阅读文档时,我看到切片是通过指向它所基于的数组的指针传递给函数的。
切片是否也通过指针传递给for循环?(在文档中找不到原因)
如果是这样的话,我猜为什么输出正好是0A,1 M,2C,-因为,最初,切片是通过指针传递给循环的,当切片的容量在循环的第一次迭代中加倍时,print(i,s)值仍然是基于基数组打印的。这是真的吗?

w9apscun

w9apscun1#

append可以分配一个新的数组。它确实可以。在第一个append之后,x现在是一个副本,您正在循环原始数组。对x的更改现在对s没有影响。
让我们用更多的调试来标记这个循环。

x := []string{"A", "B", "C"}

for i, s := range x {
    fmt.Printf("Start: i=%v s=%v x=%p %v\n", i, s, x, x)
    x[i+1] = "M"
    fmt.Printf("After x[i+1] = \"M\": i=%v s=%v x=%p %v\n", i, s, x, x)
    x = append(x, "Z")
    fmt.Printf("After Append: i=%v s=%v x=%p %v\n", i, s, x, x)
    x[i+1] = "Z"
    fmt.Printf("After x[i+1] = \"Z\": i=%v s=%v x=%p %v\n\n", i, s, x, x)
}

And the result ...

Start: i=0 s=A x=0xc0000161b0 [A B C]
After x[i+1] = "M": i=0 s=A x=0xc0000161b0 [A M C]
After Append: i=0 s=A x=0xc000062180 [A M C Z]
After x[i+1] = "Z": i=0 s=A x=0xc000062180 [A Z C Z]

Start: i=1 s=M x=0xc000062180 [A Z C Z]
After x[i+1] = "M": i=1 s=M x=0xc000062180 [A Z M Z]
After Append: i=1 s=M x=0xc000062180 [A Z M Z Z]
After x[i+1] = "Z": i=1 s=M x=0xc000062180 [A Z Z Z Z]

Start: i=2 s=C x=0xc000062180 [A Z Z Z Z]
After x[i+1] = "M": i=2 s=C x=0xc000062180 [A Z Z M Z]
After Append: i=2 s=C x=0xc000062180 [A Z Z M Z Z]
After x[i+1] = "Z": i=2 s=C x=0xc000062180 [A Z Z Z Z Z]

注意在第一个append之后,x的地址是如何改变的。任何x[i+ ] =?no longer affect s`。

相关问题