捕获迭代变量
现在假设有一个程序必须创建一系列的目录之后又会删除它们。可以用一个包含函数变量的slice进行清理操作
1 | var rmdirs []func() |
在这段代码里循环变量d
被赋值给新的局部变量dir
,而不是直接去使用循环变量d
,以下是错误示例
1 | var rmdirs[] func() |
错误的原因在于,在Golang中循环里创建的所有函数变量共享相同的变量,也就是说在调用清理函数前dir
已经被更新很多次了,而清理函数只是把最后一次的dir
清理了,解决该问题的方法是引入一个内部变量,就像dir
变量是一个和外部变量同名的变量,只不过是一个副本,这看起来似乎是多余的但实际上是程序能否正确运行的关键
1 | for _, dir := range tempDirs() { |
这种问题不只存在于使用range的for循环里。在下面的循环中也因捕获索引变量i
而导致同样的问题
1 | var rmdirs []func() |
在Golang中迭代变量捕获的问题是很频繁的,因为这会推迟函数的执行时机,直到循环结束。所以要倍加留意在循环中的函数变量。