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]()
        }
    } 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?