Golang范围表达式的奇怪行为

mawenbao

我有这个测试代码,它只是从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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

奇怪的行为正则表达式

来自分类Dev

正则表达式奇怪的行为

来自分类Dev

奇怪的正则表达式行为-Python

来自分类Dev

正则表达式模式的奇怪行为

来自分类Dev

正则表达式中捕获组的奇怪行为

来自分类Dev

令牌化中的奇怪正则表达式行为

来自分类Dev

MongoDB $ dateToString格式表达式%G奇怪的行为

来自分类Dev

奇怪的vim正则表达式行为

来自分类Dev

正则表达式模式的奇怪行为

来自分类Dev

正则表达式的行为很奇怪。我想念什么?

来自分类Dev

%s在正则表达式中显示奇怪的行为

来自分类Dev

列表中正则表达式匹配的奇怪行为

来自分类Dev

在 lambda 表达式中更改对象的奇怪行为

来自分类Dev

Java 中正则表达式的奇怪行为

来自分类Dev

奇怪的lambda表达式

来自分类Dev

与包含点的字符串匹配时奇怪的正则表达式行为

来自分类Dev

带有脚本块和正则表达式替换的奇怪Powershell行为

来自分类Dev

python3:使用正则表达式进行模式匹配时出现奇怪的行为

来自分类Dev

bash $ {VAR // search / replace}和奇怪的正则表达式行为

来自分类Dev

讨厌的正则表达式和奇怪的字符串行为

来自分类Dev

Python 3中正则表达式匹配数字的奇怪行为

来自分类Dev

return语句中的奇怪表达式

来自分类Dev

Python正则表达式行为

来自分类Dev

MySQL正则表达式行为

来自分类Dev

为什么我的正则表达式有奇怪的行为?这是一个错误吗?

来自分类Dev

具有正则表达式和注释的Perl程序表现出奇怪的行为

来自分类Dev

页面范围的正则表达式

来自分类Dev

正则表达式范围与backref

来自分类Dev

OFFSET和LIMIT表达式范围