dongzhan1492 2018-07-29 07:16
浏览 247
已采纳

函数列表中的Golang函数具有最后一个值

In the following snippet I create a func list that should, the way I see it, contain funcs that print the numbers 0 1 2.

package main

import "fmt"

func main() {
    flist := make([]func(), 0)
    for i := 0; i < 3; i++ {
        flist = append(flist, func() { fmt.Printf("%d ", i) })
    }
    for j := 0; j < 3; j++ {
        flist[j]()
    }
}

However, all funcs in flist are the same main.main.func1 and the output is

3 3 3

even though i never reaches the value 3 in the loop. This would make me thing the func is simply taking the address of i, creating the same func every time but that i is out of scope when the funcs are called later.

What am I missing here?

  • 写回答

1条回答 默认 最新

  • doupuzhimuhan9216 2018-07-29 07:25
    关注

    If we think of what code is generated for those functions, it is identical indeed: the same variable is used every time. Even though i is out of scope after the loop, it becomes the part of the closures and its latest value is seen by the function when they run. By the moment the loop exits, it's 3. If you want to bind a closure to the particular value and guard it from further changes, you may create a narrow-scoped variable, like this:

    package main
    
    import "fmt"
    
    func main() {
        flist := make([]func(), 0)
        for i := 0; i < 3; i++ {
            j := i  // a different variable for each iteration
            flist = append(flist, func() { fmt.Printf("%d ", j) })
        }
        for j := 0; j < 3; j++ {
            flist[j]()
        }
    } 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 Dkeil5 CT107D单片机的程序编写
  • ¥30 Ubuntu20.04中PVN3D复现过程交叉编译问题
  • ¥15 模拟电路求复阻抗和传递函数,请各位拍照写一下解答过程
  • ¥60 不懂得怎么运行下载来的代码
  • ¥15 CST导出3D模型图为什么和软件显示不一样?
  • ¥15 加热反应炉PLC控制系统设计(相关搜索:梯形图)
  • ¥15 python 用Dorc包报错,我的写法和网上教的是一样的但是它显示无效参数,是什么问题
  • ¥15 经过滑动平均后的一维信号还原用什么结构好呢?
  • ¥15 指定IP电脑的访问设置
  • ¥30 matlab ode45 未发现警告,但是运行出错