我有这个测试代码,它只是从int slice中删除偶数:
package main
import "fmt"
func main() {
a := []int{0, 1, 2, 3}
for i, v := range a {
fmt.Printf("i: %d v: %d\n", i, v)
fmt.Println("before", a)
if v%2 == 0 {
// delete a[i]
a = append(a[:i], a[i+1:]...)
}
fmt.Println("after", a, "\n")
}
fmt.Println("final", a)
}
输出为:
i: 0 v: 0
before [0 1 2 3]
after [1 2 3]
i: 1 v: 2
before [1 2 3]
after [1 3]
i: 2 v: 3
before [1 3]
after [1 3]
i: 3 v: 3
before [1 3]
after [1 3]
final [1 3]
您也可以在http://play.golang.org/p/BFPxekBggS上找到它。我的问题是,为什么变量v
在最后两次迭代中求值为3?提前致谢。
在内部,切片就像一个包含三个元素的结构:
cap(slice)
len(slice)
你的循环运行之前,支持阵列a
是[0, 1, 2, 3]
用cap(a) == len(a) == 4
。
当您a
使用以下代码进行修改时:
a = append(a[:i], a[i+1:]...)
a
由于新的长度小于容量,因此新的值将共享原始的后备阵列。因此,在第一次迭代中的修改之后,背衬阵列现在包含[1, 2, 3, 3]
用len(a) == 3
。数组中的最后一个元素通过常规的分片操作不可见,但保留其旧值。
在第二次迭代中,切片再次被缩短,因此支持数组现在[1, 3, 3, 3]
为len(a) == 2
。
现在,当循环运行时,range
表达式仅被评估一次,因此无论您在循环中进行了什么更改,它将始终导致4次迭代。它还将从相同的后备数组返回结果,这将解释您所看到的数字。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句