Go言語における例外処理

https://qiita.com/shoichiimamura/items/13199f420ebaf0f0c37c
https://qiita.com/nayuneko/items/9534858156dfd50b43fb
go言語では例外を、errorとpanicの2種類に分けて、それぞれ全く異なった扱い方をする。
一般的な言語で言うと、問題があったことを戻り値nullなどで示すのがerror。Exceptionオブジェクトをthrowするのがpanic。

error

例えばファイルを開く関数に存在しないパスを渡した場合に発生するのがこれ。通常運用で発生しうる例外。
複数戻り値の一部としてerror値を返す。
返されたerrorをもとにどのような処理をするかは、完全に呼び出し側に任される。
例えば以下のような感じ。

data, err := ioutil.ReadFile(filePath)
if err != nil {
    fmt.Println("file nothing!")
    return
}
fmt.Println("read text:", data)

panic

例えば配列のインデックス範囲外にアクセスしようとした場合に発生するのがこれ。通常運用で発生してはいけない例外。
panicの動きはExceptionオブジェクトをthrowした場合と似ており、その場で処理を停止してpanicが捕捉されるところへ制御が移る。捕捉されなかった場合、システムエラーメッセージが表示されてプログラムが終了する。
go言語にはtry-catch構文が存在しないので、catchではなくdefer構文とrecover関数をつかってpanicを捕捉する。
またthrow命令を使うのと同様に、panic関数で自分でpanicを発生させることができる。
例えば以下のような感じ。

func main() {
    defer func() {
        err := recover();
        if err != nil {
            fmt.Println("panic info:", err)
        }
    }()
    
    invokePanic();
}
func invokePanic() {
    panic("panic!!");
}