Go沒有像Java那樣的異常機制,它不能拋出異常,而是使用了 panic和recover機制。一定要記住,應當把它作為最後的手段來使用,也就是說,我們的代碼中應當沒有,或者很少有panic這樣的東西。 ...
一、延遲是什麼?
•即延遲( defer)語句,延遲語句被用於執行一個函數調用,在這個函數之前,延遲語句返回。
一、延遲函數
1、可以在函數中添加多個defer語句。
•當函數執行到最後時,這些defer■語句會按照逆序執行,最後該函數返回。特別是當你在進行一些打開資源的操作時,遇到錯誤需要提前返回,在返回前你需要關閉相應的資源,不然很容易造成資源泄露等問題
•如果有很多調用defer,那麼defer是採用後進先出模式
•在離幵所在的方法時,執行(報錯的時候也會執行)
package main import "fmt" import ( "base" ) func main() { defer funcA() funcB() defer funcC() fmt.Println("main over...") } func funcA() { fmt.Println("這是funcA") } func funcB() { fmt.Println("這是funcB") } func funcC() { fmt.Println("這是funcC") }View Code
延遲方法(defe的數據結構類似於棧)
package main import "fmt" type person struct { firstName, lastName string } func (p person) fullName() { fmt.Printf("%s %s", p.firstName, p.lastName) } func main() { p := person{"Steven" , "Wang"} defer p.fullName() fmt.Print("Welcome ") }View Code
帶參數的defer函數
package main import "fmt" func main() { a := 5 b := 6 defer printAdd(a, b, true) a = 10 b = 7 printAdd(a, b, false) } func printAdd(a, b int, flag bool) { if flag { fmt.Printf("延遲執行函數printAdd() ,參數a,b分別為%d, %d , 兩數之和為:%d\n", a, b, a+b) } else { fmt.Printf("未延遲執行函數printAdd() ,參數a,b分別為%d, %d , 兩數之和為:%d\n", a, b, a+b) } }View Code
二、宕機panic和宕機恢復recover
(―)、panic和recover機制
1、概述:
• panic:詞義__恐慌recover:"恢復_■
• Go沒有像Java那樣的異常機制,它不能拋出異常,而是使用了 panic和recover機制。一定要記住,應當把它作為最後的手段來使用,也就是說,我們的代碼中應當沒有,或者很少有panic這樣的東西。
• go語言利用panicO, recover(),實現程式中的極特殊的異常處理
〇 panicO,讓當前的程式進入恐慌,中斷程式的執行
〇 recoverO,讓程式恢復,必須在defer函數中執行
〇 Panics—個內建函數,可以中斷原有的控制流程,進入一個令人恐慌的流程中。
〇當函數 F調用panic,函數 F的執行被中斷,但是F中的延遲函數會正常執行,然後F返回到調用它的地方。在調用的地方,F的行為就像調用了panic。這一過程繼續向上,直到發生panic的goroutine中所有調用的函數返回,此時程式退出。
〇恐慌可以直接調用panic產生。也可以由運行時錯誤產生,例如訪問越界的數組。
〇 Recover是一個內建的函數,可以讓進入令人恐慌的流程中的goroutine恢復過來。
〇 recover僅在延遲函數中有效。在正常的執行過程中,調用recover會返回nil,並且沒有其它任何效果。如果當前的goroutine陷入恐慌,調用recover•可以捕獲到panic的輸入值,並且恢復正常的執行
package main import "fmt" func main() { funcA() funcB() funcC() fmt.Println("main over") } func funcA() { fmt.Println("這是funcA") } func funcB() { defer func() { if msg := recover(); msg != nil { fmt.Println("恢復啦,獲取recover的返回值:", msg) } }() fmt.Println("這是funcB") for i := 0; i < 10; i++ { fmt.Println("i:", i) if i == 5 { //panic("funcB恐慌啦") } } } func funcC() { defer func() { fmt.Println("執行延遲函數") msg := recover() fmt.Println("獲取recover的返回值:", msg) }() fmt.Println("這是funcC") panic("funcC恐慌了") }View Code