最近趣味でGoを触り始めたSE。
表題のエラー処理(Panic, Recover, Defer)について自分なりに理解したことを残す。
Defer
呼び出されたときに、最後に必ず実行されるべき処理を書いておく。
(DB ConnectionのClose処理とか)
package main
import (
"fmt"
)
func main() {
fmt.Println("Begin main")
DeferFunc()
fmt.Println("End main")
}
func DeferFunc() {
defer func() {
fmt.Println("End func")
}()
fmt.Println("Begin func")
}
実行結果
$go run ./main.go
Begin main
Begin func
End func
End main
Panic
panic("HogeHoge")
すると、deferの処理を呼び出してcloseする。
func DeferFunc() {
defer func() {
fmt.Println("End func")
}()
panic("HogeHoge")
fmt.Println("Begin func")
}
$go run ./main.go
Begin main
End func # Panicすると、以降の関数内の処理が呼ばれない
panic: HogeHoge # Panicの内容が表示され、
goroutine 1 [running]:
main.DeferFunc()
/opt/recover/main.go:17 +0x5c
main.main()
/opt/recover/main.go:9 +0x6d
exit status 2
panic("HogeHoge")
以降の処理が実行されず、deferを実行してRuntimeエラーを起こして死ぬ。
Recover
deferの処理内で、errorを扱うときに使用?また、Recoverを実行すると、プロセスは死なない模様。
func DeferFunc() {
defer func() {
fmt.Println("End func")
if err := recover(); err != nil {
fmt.Println("Runtime Error:", err)
}
}()
panic("HogeHoge")
fmt.Println("Begin func")
}
$go run ./main.go
Begin main
End func
Runtime Error: HogeHoge # Recover処理の中身
End main # End mainが呼ばれている
分からなかったこと
- Recoverしたけど再度Panicでプロセスを殺したい場合(Exceptionの種類に応じてRecoverするか、Errorにして落とすかみたいなことができるのか)
以上