问题
loop1()在于您将函数文字存储在
actions引用 循环变量
的映射中
cmd。该循环变量只有一个实例,因此在循环后调用
actions映射中存储的函数时,所有实例都将引用此单个循环变量(之所以保留,是因为函数/闭包仍然引用了该变量),但是它
在执行 时的值将是
for循环设置的最后一个值,即
cmds切片中的最后一个值(即
"update",因此您将看到
"update"打印3次)。
一个简单的解决方法是制作此循环变量的副本,因此,每次迭代,每个函数文字都将有其自己的副本,该副本与循环变量“分离”:
func loop1() { actions := make(map[string]func()) for _, cmd := range cmds { cmd2 := cmd actions[cmd] = func() { fmt.Println(cmd2) // Refer to the detached, copy variable! } } for _, action := range actions { action() }}这样,输出
loop1()(在Go Playground上尝试):
updatecreatedelete
这不是的问题
for ...range,这是因为闭包引用的是同一个变量,并且您不会仅在循环之后立即使用变量的值。当您打印此变量的值时,所有变量都将打印相同的最后一个值。



