- Defer
func trace(s string) string {
fmt.Println("entering:", s)
return s
}
func un(s string) {
fmt.Println("leaving:", s)
}
func a() {
defer un(trace("a"))
fmt.Println("in a")
}
func b() {
defer un(trace("b"))
fmt.Println("in b")
a()
}
func main() {
b()
}
以上这一段的返回值是
entering:b
in b
entering:a
in a
leaving:a
leaving:b
然而我一开始以为是
in b
in a
entering:a
leaving:a
entering:b
leaving:b
这是因为没考虑到defer的执行机制:defer以defer初次定义时的注入参数值,作为defer函数被调用时的注入参数(function)。因此在defer un(trace("a"))和defer un(trace("b"))中,注入参数即trace("a")和trace("b")被立即执行。
原文:The arguments to the deferred function (which include the receiver if the function is a method) are evaluated when the defer executes, not when the call executes. Besides avoiding worries about variables changing values as the function executes, this means that a single deferred call site can defer multiple function executions. Here's a silly example.