0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Goにはtry/catchがないが、panicやrecoverをむやみにつかってはいけない。一般的には、error型で返すのが好ましい。

panicとは

Go Playground

func main() {
	fmt.Println("a")
	panic("foo")
	fmt.Println("b")
}

パニックが発生すると、現在の goroutine がリターンするか、recover でパニックが捕捉されるまで、パニックはコールスタックをさかのぼる。

以下はrecoverで捕捉する例である。

func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("recover", r)
		}
	}()

	f() // パニックが発生するfをコールする
}

func f() {
	fmt.Println("a")
	panic("foo")
	fmt.Println("b")
}

recoverで捕捉されると、goroutineは終了しない。
recoverを呼び出すのは、deferに与えられた関数内だけで有効。recover関数はnilを返し、何も効果はない

パニックを発生させるべきとき

  • 純粋なプログラマーエラー
  • アプリケーションが必須依存関係を必要とするにも関わらず、初期化に失敗するとき

純粋なプログラマーエラー

net/httpパッケージのWriteHeaderでは、ステータスコードが有効化どうかを検査するためにcheckWriteHeaderCode()が呼ばれる。

func checkWriteHeaderCode(code int) {
	if code < 100 || code > 999 {
		panic(fmt.Sprintf("invalid WriteHeader code %v", code))
	}
}

ステータスコードが不正な値をとるとパニックを起こす。

その他にもdatabase/sqlパッケージのRegister()が0位に挙げられる。

アプリケーションが必須の依存関係の作成に失敗するとき

新たな顧客アカウントを作成するためのサービスを公開するとき、提供された電子メールアドレスの検証を正規表現を用いて行う。

regexpパッケージには、文字列から正規表現を作成する関数として、以下の2つがある。

  • Compile : *regexp.Regexpとエラーを返す
  • MustCompile : エラーが発生したらパニックを発生させる

まとめ

ほとんどの場合は、最後の戻り値として、error型を返すべきである。

参考文献

  1. 100 Go Mistakes and How to Avoid Them
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?