当前位置: 首页 > 面试题库 >

除非复制变量,否则go例程中的闭包的作用域不正确

祁博涛
2023-03-14
问题内容

我在以goroutines运行的函数中看到不正确的值。除非将它们复制到新变量中,否则它们似乎并没有从调用它们的范围中捕获值。

http://play.golang.org/p/YZYi-IVuYm

http://play.golang.org/p/z88G99XSi6


问题答案:

您或者需要在本地上下文中重新分配变量,以便闭包可以捕获值:

http://play.golang.org/p/-NO4S4qCZf

package main

import "fmt"
import "time"

func main() {
    l := []int{1, 2, 3}
    for idx, item := range l {
        theIdx, theItem := idx, item
        go func() {
            fmt.Println(theIdx, theItem)
        }()
    }
    time.Sleep(time.Second)
}

或者您将值传递给goroutine并向函数添加参数

http://play.golang.org/p/5gNToDWSQR

package main

import "fmt"
import "time"

func main() {
    l := []int{1, 2, 3}
    for idx, item := range l {
        go func(idx, item int) {
            fmt.Println(idx, item)
        }(idx, item)
    }
    time.Sleep(time.Second)
}


 类似资料:
  • JavaScript 是一种非常面向函数的语言。它给了我们很大的自由度。在 JavaScript 中,我们可以随时创建函数,可以将函数作为参数传递给另一个函数,并在完全不同的代码位置进行调用。 我们已经知道函数可以访问其外部的变量。 但是,如果在函数被创建之后,外部变量发生了变化会怎样?函数会获得新值还是旧值? 如果将函数作为参数传递并在代码中的另一个位置调用它,该函数将访问的是新位置的外部变量吗

  • 主要内容:局部变量,全局变量,形式参数一个变量(常量、类型或函数)在程序中都有一定的作用范围,称之为作用域。 了解变量的作用域对我们学习Go语言来说是比较重要的,因为Go语言会在编译时检查每个变量是否使用过,一旦出现未使用的变量,就会报编译错误。如果不能理解变量的作用域,就有可能会带来一些不明所以的编译错误。 根据变量定义位置的不同,可以分为以下三个类型: 函数内定义的变量称为局部变量 函数外定义的变量称为全局变量 函数定义中的变量称

  • 本文向大家介绍php闭包中使用use声明变量的作用域实例分析,包括了php闭包中使用use声明变量的作用域实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php闭包中使用use声明变量的作用域。分享给大家供大家参考,具体如下: 如上,闭包中使用use声明的变量来自于生成闭包实例时所在作用域内的同名变量,而不是来自于运行闭包时所在作用域内的同名变量。 而闭包的函数参数则是和正常的函数

  • 作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。 Go 语言中变量可以在三个地方声明: 函数内定义的变量称为局部变量 函数外定义的变量称为全局变量 函数定义中的变量称为形式参数 接下来让我们具体了解局部变量、全局变量和形式参数。 局部变量 在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。 以下实例中 main() 函数使用了局

  • 本文向大家介绍浅谈Python中的作用域规则和闭包,包括了浅谈Python中的作用域规则和闭包的使用技巧和注意事项,需要的朋友参考一下 在对Python中的闭包进行简单分析之前,我们先了解一下Python中的作用域规则。关于Python中作用域的详细知识,有很多的博文都进行了介绍。这里我们先从一个简单的例子入手。 Python中的作用域 假设在交互式命令行中定义如下的函数: 上述代码先给a赋值1,

  • 问题内容: Go编译器不应该将循环变量捕获为本地分配的闭包变量吗? 长版: 这也引起了我对C#的困惑,并且我试图理解它。这就是为什么它在C#5.0中已得到修复(原因:循环变量 不能 在循环体内改变)以及未在C#循环中对其进行修复的原因(原因:循环变量 可以 在循环体内改变)。 现在(对我而言),Go中的循环看起来很像C#中的循环,但是尽管事实是我们无法更改这些变量(例如和中)。仍然我们必须首先将它