defer panic recover
阿新 • • 發佈:2019-01-09
defer
1.詞義
defer推遲 recover恢復 panic恐慌
2.panic
panic 型別interface{}型別
panic恐慌 不會再往下執行了
3.recover
panic 之後不會立刻返回 會傳遞至defer defer裡面有recover的話 會進行捕獲panic的內容
4.defer
defer推遲 可以多次推遲 棧的資料結構
5.正常情況
package main import ( "fmt" ) func main() { test() } func minicError(key string) error { return fmt.Errorf("mimic error: %s", key) } func test() { fmt.Println("start test") err := minicError("1") defer func() { fmt.Println("start defer") if err != nil { fmt.Println("defer error:", err) } }() fmt.Println("end test") } -------------------------------------- start test end test start defer defer error: mimic error:
6.defer與return
return是在defer之後執行的
7.recover與panic
無值時候:Recover方法被呼叫,但是沒有任何的panic發生,recover方法只會返回nil;
有值時候:如果有panic發生,那麼panic就停止 並且把panic的賦值傳遞給recover。
總結:如果有了panic 那麼後面的都不執行了 但是會把值傳遞給recover recover會捕獲panic的值 並且程式不會崩潰
7.例子
這個例子說明了recover進行捕獲panic的內容
package main import "fmt" import "math" func foo(a int) { defer fmt.Println("foo退出來了") defer func() { if r := recover(); r != nil { fmt.Printf("捕獲到的錯誤:%s\n", r) } }() if a < 0 { panic("必須輸入大於0的數") } fmt.Println("該數的方根為:", math.Sqrt(float64(a))) } func main() { var a int a = 10 fmt.Printf("a=%d\n", a) foo(a) var b int b = -10 fmt.Printf("b=%d\n", b) foo(b) fmt.Println("該goroutine還可以執行") } // a=10 // 該數的方根為: 3.1622776601683795 // foo退出來了 // b=-10 // 捕獲到的錯誤:必須輸入大於0的數 // foo退出來了 // 該goroutine還可以執行