为了账号安全,请及时绑定邮箱和手机立即绑定

转到:将var转换为匿名函数

转到:将var转换为匿名函数

Go
aluckdog 2021-04-30 14:08:46
我在将变量传输到匿名函数时遇到麻烦。有解决方案吗?import  "github.com/lxn/walk"***var openAction [12]*walk.Actionfor i := 0; i < 12; i++ {    openBmp, err := walk.NewBitmapFromFile(_films[i][0])    if err != nil {        log.Printf("Open bitmap for buildBody() :%v\n", err)    }    openAction[i] = walk.NewAction()    openAction[i].SetImage(openBmp)    openAction[i].SetText(_films[i][2])    openAction[i].Triggered().Attach( func(){        exec(i)    })    mw.ToolBar().Actions().Add(openAction[i])}exec(i)我总是= 11
查看完整描述

3 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

我认为这将为您提供所需的东西:


openAction[i].Triggered().Attach(func(x int) func() {

    return func() { exec(x) }

}(i))

诀窍是让您的匿名函数返回一个匿名函数,并且每个创建的函数都将包围i的每个值。


查看完整回答
反对 回复 2021-05-10
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

for i := 0; i < 12; i++ {

    i := i

    ...

看起来很疯狂,这是您会在Go代码中看到的东西。它是由闭包的工作方式和变量的作用域产生的。您的匿名函数是一个捕获i的闭包。具体来说,它捕获的是一个名为i的变量,而不是i的当前值,并且它捕获范围内的任何i。在您的原始代码中,这是循环变量,对于循环的每次迭代,它都是相同的变量。您所有的闭包都捕获了相同的变量。增加的会i := i在每次迭代中声明一个新变量。现在,每个闭包都将捕获此新变量,并且在每次迭代中它将是一个不同的变量。


更详细地讲,循环变量i的范围是for语句。这包括循环块,但是由于循环变量i的声明不在该块之外,因此在块内声明一个具有相同名称的新变量是合法的,并在该点处创建一个新变量。然后,将循环变量阴影化。通常,这样声明的变量会放在堆栈上,但是在这种情况下,编译器转义分析发现,当闭包超出范围的末尾时,您的闭包仍在引用此块变量,因此该变量被放置在堆。在每次迭代中,将重新输入该块,并在堆上放置一个新变量i。


查看完整回答
反对 回复 2021-05-10
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

您正在遇到go's for循环的怪癖。循环中的i变量不是每次迭代的新变量。因此,您所有的闭包都关闭在其值在其下更改的同一变量上。当您的代码在循环后运行时,所有函数的关闭值i都为11。

解决方案是将i传递给一个函数,然后该函数返回另一个关闭函数arg的函数。这就是Adam Crosslands解决方案起作用的原因。


查看完整回答
反对 回复 2021-05-10
  • 3 回答
  • 0 关注
  • 211 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信