如果切片在循环内增加,将如何迭代该切片?

问题描述 投票:0回答:1

当我遍历幻灯片上的 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) 值仍然基于基本数组打印。这是真的吗?

go slice
1个回答
0
投票
  1. range
    只检查一次
    x
    的大小。
  2. 你正在用 Z 覆盖除第一个元素之外的每个元素。
  3. 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 覆盖它。

© www.soinside.com 2019 - 2024. All rights reserved.