panic, recover
panic 可以讓執行中的程式直接中斷跳出。
package main
import "fmt"
func main() {
f()
fmt.Println("Returned normally from f.")
}
func f() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
fmt.Println("Calling g.")
g(0)
fmt.Println("Returned normally from g.")
}
func g(i int) {
if i > 3 {
fmt.Println("Panicking!")
panic(fmt.Sprintf("%v", i))
}
defer fmt.Println("Defer in g", i)
fmt.Println("Printing in g", i)
g(i + 1)
}
會印出如下
Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.
panic 後會中斷function並立刻執行defer,所以會印出剛才存在defer stack 中的東西
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
然後panic 後會再往上拋到 f,執行 f 的 defer
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
recover()
會讓 f 改為正常執行,從panic復原
並繼續執行
Recover
如果發生了 panic,可以使用 recover來復原,這個函式必須在被 defer 的函式中執行才有效果,若在被 defer 的函式外執行,recover 會傳回 nil,recover 的 defer 必須寫在panic之前先設定好
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
因為panic會讓中斷以外會讓程式結束,所以為了避免程式直接結束會用recover來讓程式繼續執行,並輸出error log
Last updated
Was this helpful?