defer的陷阱
当使用defer
时,请记住如下几点:延迟函数在函数的末尾调用;延迟语句的作用域为函数级别,而不是代码块级别。
换句话说:延迟调用只在函数结束退出时执行,并不在if
或for
语句创建的代码块中执行。
您也许以为上述延迟语句会在退出if
分支时执行,但事实上它只在函数的最后被执行。
在延迟函数中使用外部变量
一个常犯的错误是认为上述代码会输出0
和1
。当我们看到defer
时,它们就是i
的值。
但是,defer
创建了一个闭包,它只捕获了i
的引用,而不是变量的值。
我们看看上述代码实际会怎样执行就清楚了:
现在已经清楚了延迟调用fmt.Println
时为何两次i
的值都是2。
我们可以通过强制捕获变量来修正上述行为:
这样闭包的开销可能会稍微大些,因为它需要分配对象来收集由闭包捕获的所有变量。
最后更新于