首页 > 后端开发 > Golang > 为什么 Go 的'for range”循环与函数文字表现出不同的行为?

为什么 Go 的'for range”循环与函数文字表现出不同的行为?

Susan Sarandon
发布: 2024-12-10 20:52:11
原创
421 人浏览过

Why Does Go's `for range` Loop Exhibit Different Behavior with Function Literals?

了解 Go 中不同的循环行为

在 Go 中构造循环时,了解 for range 循环的行为至关重要。考虑以下两个表现出不同行为的循环变体:

循环变体 1:

func loop1() {

    actions := make(map[string]func())

    for _, cmd := range cmds {
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
    for _, action := range actions {
        action()
    }
}
登录后复制

循环变体 2:

func loop2() {

    actions := make(map[string]func())

    for i, cmd := range cmds {
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
    for _, action := range actions {
        action()
    }
}
登录后复制

输出观察:

  • Loop1 产生输出:“update”(重复 3 次)
  • Loop2 产生输出:“delete”、“update”、“create”

循环变化中的根本问题1:

问题出在 func Loop1() 循环上。每次循环迭代都会向操作映射分配一个函数文字。该函数文字引用循环变量 cmd。然而,只有一个 cmd 实例,当循环结束时,它保存命令片中的最后一个值,即“update”。这意味着所有封闭的函数引用相同的循环变量(cmd),这会导致所有函数在调用时打印“update”。

解决方案:

要纠正这个问题,在每次循环迭代中制作循环变量的副本,因此每个函数字面量都有自己独立的复制:

func loop1() {
    actions := make(map[string]func())

    for _, cmd := range cmds {
        cmd2 := cmd
        actions[cmd] = func() {
            fmt.Println(cmd2) // Refer to the detached, copy variable!
        }
    }
    for _, action := range actions {
        action()
    }
}
登录后复制

结论:

综上所述,在使用 for range 循环时,考虑循环变量的范围和引用至关重要。确保在必要时创建循环变量的副本可确保正确的行为,特别是在处理引用这些变量的函数文字时。

以上是为什么 Go 的'for range”循环与函数文字表现出不同的行为?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板