在《深入defer》这篇中我们解释了defer在代码中是如何运行的,上篇文章中我们遗留了一个问题,这篇文章我们解答一下这个问题。
defer是什么时候被调用的
在使用defer的时候,我们知道defer通常是用来释放io资源的,但是如果我们在defer中做一些其它的事情呢,那么程序的运行结果可能跟我们的预期并不一致,下面通过一些例子我们来验证defer与return的执行顺序。
defer是在return之后执行的?
package main
import (
"log"
)
func main() {
c := test()
log.Println("main", c)
}
func test() int {
a:=1
log.Println(a)
defer func() {
a = 2
log.Println("defer", a)
}()
return a
}
# out
test 1
defer 2
main 1
这个例子中,我们在test方法中定义个变量a,并在函数的最后返回了这个a的值,在main函数中定义了变量c来接收这个值,test方法中我们使用defer栈修改了这个a的值,执行结果如上。
通过这个例子中的结果得出结论:defer是在return之后执行的。
defer是在return之前执行的?
我们通过一个具名返回值来改写上面的例子:
package main
import (
"log"
)
func main() {
a := test()
log.Println("main", a)
}
func test() (a int){
a=1
log.Println(a)
defer func() {
a = 2
log.Println("defer", a)
}()
return a // 1
}
# out
test 1
defer 2
main 2
这个结果是不是有种被啪啪打脸的感觉呢? 如果按照defer实在return之后执行的结论,那么返回的应该是a当时的值,结果main中打印的a并不是1而是2。
defer与return到底谁先执行?
讨论的篇幅过大,令起一篇:《defer与return到底谁先执行?》