前言 做了幾道關於defer的測試題,嚇了一大跳,感覺自己之前的理解有些問題,所以寫下這篇博客,加深下印象。 正文: 多個defer的執行順序: 先進後出,類似於棧的特性。 下麵我們來測試下: 1.defer 與 panic: func deferAndPanic() { defer func() ...
前言
做了幾道關於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遇到嵌套函數的調用,入棧的時候需要先解析出來該內部函數的值,再壓入棧內
|不驕不躁,保持學習