func 列表中的 Golang funcs 取最后一个值

Golang funcs in func list take last value

在下面的代码片段中,我创建了一个函数列表,按照我的看法,它应该包含打印数字 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]()
    }
}

但是,flist中的所有函数都是相同的main.main.func1,输出是

3 3 3

即使 i 从未在循环中达到值 3。这会让我觉得 func 只是获取 i 的地址,每次都创建相同的 func,但是当稍后调用 func 时 i 超出范围。

我在这里错过了什么?

如果我们考虑为这些函数生成的代码,它们确实是相同的:每次都使用相同的变量。即使 i 在循环之后超出范围,它也成为闭包的一部分,并且当它们 运行 时函数可以看到它的最新值。到循环退出的那一刻,它是 3。如果您想将闭包绑定到特定值并保护它免受进一步更改,您可以创建一个窄范围变量,如下所示:

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]()
    }
}