输出:1
四
func t4() (a int) {
defer func(a int) {
a++
}(a)
return 1
}
输出:1
结论:return 不是原子操作。
os.Exit
func main() {
defer fmt.Println("1")
fmt.Println("main")
os.Exit(0)
}
输出:main
结论:当os.Exit()方法退出程序时,defer不会被执行。
不同协程
func main() {
GoA()
time.Sleep(1 * time.Second)
fmt.Println("main")
}
func GoA() {
defer (func(){
if err := recover(); err != nil {
fmt.Println("panic:" + fmt.Sprintf("%s", err))
}
})()
go GoB()
}
func GoB() {
panic("error")
}
GoB() panic 捕获不到。
结论:defer 只对当前协程有效。
这个问题怎么解?咱们下回再说。
接下来,咱们分析下文章开头的问题吧。
答案解析
先列出答案:
B 1 2 3
D 3 2 5
C 3 5 8
A 1 3 4
其实上面那道题,可以拆解为:
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
x := 1
y := 2
tmp1 := calc("B", x, y)
defer calc("A", x, tmp1)
x = 3
tmp2 := calc("D", x, y)
defer calc("C", x, tmp2)
y = 4
}
所以顺序就是:B D C A。
执行到 tmp1 时,输出:B 1 2 3。
执行到 tmp2 时,输出:D 3 2 5。
根据 defer 执行顺序原则,先声明的后执行,所以下一个该执行 C 了。
又因为传参是值赋值,所以在 A 的时候,无法用到 x = 3 和 y = 4,在 C 的时候,无法用到 y = 4。
执行到 C 时,输出:C 3 5 8
执行到 A 时,输出:A 1 3 4
到这,基本上 defer 就清楚了,大家可以根据自己的理解去记忆。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。









