Go/defer,panicとrecover
< Go
defer、panicとrecover
編集Goでは、ゼロ除算などのランタイムエラーが発生すると、組み込み関数 panic
が呼び出されます(詳細は ランタイム・パニック を参照してください)。
標準の動作では、panic
が発生するとプログラムは終了しますが、defer
で登録された関数(またはメソッド)は panic
が発生した際にも呼び出されます。defer
の中で組み込み関数 recover
を呼び出すことで、panic
の引数を取得することができます。
defer
、panic
、recover
を用いた例外処理は強力ですが、構造化されていないため、パッケージの API として使用するには適していません。したがって、パッケージを超えたエラー処理には適用を避けるべきです。
パッケージを超えたエラー処理には、error
インターフェースの利用が適しています。
「Go/エラー」も参照
- コード例
package main import "fmt" func main() { defer func() { if err := recover(); err != nil { fmt.Printf("%v -- recovered(main)\n", err) } }() fmt.Println(subr()) panic("User raised panic") fmt.Println("fin") } func subr() (i int) { defer func() { if err := recover(); err != nil { fmt.Printf("%v -- recovered(subr)\n", err) i = 0 } }() a, b := 1, 0 a = a / b fmt.Printf("a = %d, b = %d\n", a, b) return a }
- 実行結果
./prog.go:13:2: unreachable code Go vet exited. runtime error: integer divide by zero -- recovered(subr) 0 User raised panic -- recovered(main) Program exited.