GO(4) - error and panic
Go 中錯誤跟異常為 error 和 panic。
error 是開發者可以預期的錯誤,而 panic 是較為嚴重未預期的錯誤。
1. error:
在 Go 中如果函式有機會發生 error 則該函式除了回傳計算結果外還需將錯誤一並回傳。
定義一個除法函式,回傳型別為 (float64, error)。如果 error 沒發生則將 error 設為 nil。
package main import ( "errors" "fmt" ) func divide(a float64, b float64) (float64, error) { if b != 0 { return a / b, nil } return 0, errors.New("b can't be 0") } func main() { a := 1.0 b := 2.0 if val, err := divide(a, b); err == nil { fmt.Printf("a/b=%f\n", val) } // b = 0 // if _, err := divide(a, b); err != nil { // fmt.Println(err) // } }
2. panic:
panic 發生代表有某種開發者沒有預期的 bug。
func main() { n := 0 res := 1 / n fmt.Println(res) }
上面 res 會產生 panic: runtime error: integer divide by zero。
有趣的是這個 panic 需要 integer 跟 divide by zero 兩件事同時滿足才會發生。
例如 n 是一個 float 時不會有 panic 產生,計算結果為 +Inf。
func main() { n := 0.0 res := 1 / n fmt.Println(res) }
3. recover:
panic 可以利用 recover 進行捕獲並處理。
利用 defer 註冊一個修復的機制。
func recoverPanic() { err := recover() fmt.Println("Panic: ", err) } func main() { defer recoverPanic() n := 0 res := 1 / n fmt.Println(res) }
當 res := 1 / n 造成 panic 時程式會脫離 main(),然後 recover() 會捕捉 panic。
由於 程式會脫離 main() 所以 fmt.Println(res) 不會被執行到。
另外要注意的是 defer 是延遲執行,所以 panic 未發生時會在 fmt.Println(res) 後被執行。
func main() { defer recoverPanic() n := 0.0 res := 1 / n fmt.Println(res) }
執行結果如下,沒有 panic 時 Println 會先被呼叫顯示 +Inf 再呼叫延遲的 recoverPanic()。
+Inf Panic: <nil>
留言
張貼留言