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