go言語 panicについて

go言語 panicについて

goのプログラムを強制的に終了させるpanic。基本的にpanicの利用は推奨されないらしいですが、挙動だけ確認したかったので、panicとdeferとrecover、それぞれのサンプルコードを記述してます。

環境

  • OS  windows10 pro
  • go 1.13.8

panicサンプルコード

下記のコードは、まずはpanicのみが実行された際の挙動となります。

package main

import "fmt"

func main() {
	modoriti := test("ok")
	fmt.Println(modoriti)
}

func test(testmsg string) string {
	panic("PANIC発生")
	return testmsg
}

実行結果から、PANICが発生するとプログラムが終了されることが確認できます。

panic: PANIC発生

goroutine 1 [running]:
main.test(...)

次にpanic後に実行されるdeferを追加してみます。

※deferについてはこちら

package main

import "fmt"

func main() {
	modoriti := test("ok")
	fmt.Println(modoriti)
}

func test(testmsg string) string {
	//deferはpanicが起こっても実行されます
	defer func(msg string) {
		fmt.Println(msg)
	}("panicが発生したので実行されました")
	panic("PANIC発生")
	return testmsg
}

実行結果からpanic実行後に、deferが実行されていることが確認できます。

go run defer-test.go
panicが発生したので実行されました
panic: PANIC発生

最後にrecoverを追加して、後続処理を継続させてみます。

package main

import "fmt"

func main() {
	modoriti := test("ok")
	// recoverされるので実行されます
	fmt.Println(modoriti)
}

// deferに即時関数を渡す
func test(testmsg string) (name string) {
	//deferはpanicが起こっても実行されます
	defer func(msg string) {
		fmt.Println(msg)
		if error := recover(); error != nil {
			// panicの引数である文字列が出力されます
			fmt.Println(error)
			fmt.Println("errorを受け取りました")
			name = "ERRORが戻り値となり後続処理がmainで実行されます"
		}
	}("panicが発生したので実行されました")
	panic("PANICエラーメッセージ")

	//panic非発生時は文字列okが戻り値となる
	return testmsg
}

実行結果からpanic実行後に、deferが実行されrecoverされて、main関数内の後続処理が実行されることが確認できます。

panicが発生したので実行されました
PANICエラーメッセージ
errorを受け取りました
ERRORが戻り値となり後続処理がmainで実行されます