前言
做了几道关于defer的测试题,吓了一大跳,感觉自己之前的理解有些问题,所以写下这篇博客,加深下印象。
正文:
多个defer的执行顺序:
先进后出,类似于栈的特性。
下面我们来测试下:
1.defer 与 panic:
func deferAndPanic() { defer func() { fmt.Println("defer1") }() defer func() { fmt.Println("defer2") }() defer func() { fmt.Println("defer3") }() panic("异常内容") } func main() { deferAndPanic() fmt.Println("main 正常结束") }
结果分析:defer遇到panic会强制出栈,这个时候的结果为 :
2.defer与panic+recover
如果我们对panic进行了recover呢?
func deferAndPanic() {
defer func() { fmt.Println(“defer1”) }()
defer func() { fmt.Println(“defer2”) }()
defer func() { fmt.Println(“defer3”) }()
defer func() {
if err := recover(); err != nil {
fmt.Println(“被捕获err=”, err)
}
}()
panic(“异常内容”)
fmt.Println(“————————–“)
}
结果解析: 这个时候程序进行捕获后会回到之前程序的调用处后,继续执行。但是panic后面的语句不会执行。
看下执行结果:
3.defer与函数嵌套调用
看个例子:
func function(index int, value int) int { fmt.Println(index) return index } func main() { defer function(1, function(3, 0)) defer function(2, function(4, 0)) }
结果分析:
1.第一个defer压入栈的时候需要将他所有信息包括参数一同压入,所以会对内部的函数进行计算,得到最终值然后入栈。第二个defer同理。
2.这样最后结果返回的就是:
是不是有点惊讶!博主也是看到这些例子,才觉得自己对defer的了解浮于表面了~
总结:
defer遇到panic会强制出栈,至于panic的内容,需要看是否有捕获程序。
defer遇到嵌套函数的调用,入栈的时候需要先解析出来该内部函数的值,再压入栈内
|不骄不躁,保持学习