LoginSignup
8
7

More than 5 years have passed since last update.

GolangのDefer, Panic, Recoverについて、自分なりに理解したことを書く

Last updated at Posted at 2019-03-11

最近趣味で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にして落とすかみたいなことができるのか)

以上

8
7
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
8
7