首页 >后端开发 >Golang >为什么 Go 的'range”循环会因循环结构的不同而产生不同的结果?

为什么 Go 的'range”循环会因循环结构的不同而产生不同的结果?

Patricia Arquette
Patricia Arquette原创
2024-12-19 18:20:10988浏览

Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?

了解 Go 中不同的循环变体

在 Go 中迭代切片时,使用 range 方法时可能会遇到意外行为。让我们深入研究一下为什么不同的循环变体会产生不同的结果。

问题

考虑以下两个 for 循环变体:

loop1() {
    for _, cmd := range cmds {
        // Store a function literal that references the loop variable cmd
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
}
loop2() {
    for i, cmd := range cmds {
        // Capture the loop variable cmd using a new variable
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
}

运行这些循环结果在不同的输出:

  • loop1(): 打印“update”三次
  • loop2(): 打印“delete”、“update” ”,和“创建”

解释

loop1() 出现问题是因为存储在操作映射中的函数文字引用了循环变量 cmd。由于此循环变量只有一个实例,因此存储在映射中的所有函数都会引用它。

循环完成时,cmd 的值将是 cmds 切片中的最后一个元素“update. ”因此,当执行 actions 映射中的函数时,它们都会打印“update”。

为了规避这个问题,loop2() 使用新变量 command 捕获循环变量 cmd。这会为每次迭代创建循环变量的“独立”副本,循环完成后不受循环变量的影响。

因此,loop2() 中存储在操作映射中的每个函数都有它自己的循环变量副本,它允许每个函数打印正确的命令。

结论

在切片上进行范围操作时,重要的是要注意循环变量在所有迭代之间共享。为了避免意外行为,最好使用新变量捕获或分离循环变量,特别是在使用将在循环后执行的函数文字时。

以上是为什么 Go 的'range”循环会因循环结构的不同而产生不同的结果?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn