- Goは関数から
error型を戻すことによりエラーを処理する
- 関数が期待通りに実行された場合は
errorにはnilが返される
- 何かがうまくいかない場合は
error型の値が返される
- 呼び出し側では、
errorの戻り値をnilと比較することでチェックし、そのエラーを処理したり独自のエラーを返したりする
package main
import (
"errors"
"fmt"
"os"
)
func main() {
numerator := 20
denominator := 0
// 除数が0なのでerrにエラーメッセージがdenominator is 0が入って戻される
remainder, mod, err := calcRemainderAndMod(numerator, denominator)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("%d÷%d: 商:%d, 余り: %d\n", numerator, denominator,
remainder, mod)
}
func calcRemainderAndMod(numerator, denominator int) (int, int, error) {
// 被除数と除数をもらって、商と余り、それにerrorを返す
if denominator == 0 {
return 0, 0, errors.New("denominator is 0") // 除数が0
}
return numerator / denominator, numerator % denominator, nil
}
- Goで他の言語のように例外をスローせず、エラーを返す理由は少なくとも2つある
- 例外があるとコードの道(パス)が少なくとも1本増えてしまうため
- 例外パスがわかりにくい場合がある
- 例外が適切に処理されないとクラッシュを引き起こす
- もしくはデータが適切に初期化・変更・保存されないコードになってしまうため
- 安全性・可読性を上げるため
- Goのコンパイラは全ての変数が読まれることを強要するので、エラーの際に値が戻されることで以下の利点がある
- エラーをチェックし処理する
_を使って、エラーの無視を明示する
- エラー処理は
if文の内部にインデントして書かれ、ビジネスロジックはインデントされない。この違いにより、どのコードが主要な処理でどのコードが例外的な状況なのか視覚的に説明できる