Go/defer,panicとrecover

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go
ナビゲーションに移動 検索に移動

defer,panicとrecover[編集]

Goでは、ゼロ除算のような例外が発生すると組込み関数 panic が呼び出されます(ランタイム・パニック)。 標準状態ではブログラムが終了しますが、defer で登録された関数(あるいはメソッド; defferr)は panic が発生したときも呼び出されます。 defferr の中で組込み関数 recover を呼び出すと panic の引数を得ることができます。

defer、panic、recoverによる例外処理は強力ですが、構造化されていないため、パッケージのAPIとして使用するのには適しておらず、パッケージを超えて使用してはいけません。

パッケージを超えたエラー処理には、type error interface が適しています。

コード例
package main

import "fmt"

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("%v -- recoverd(main)\n", err)
		}
	}()

	fmt.Println(subr())
	panic("User rised panic")
	fmt.Println("fin")
}

func subr() (i int) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("%v -- recoverd(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 -- recoverd(subr)
0
User rised panic -- recoverd(main)

Program exited.