9.1 エラー処理の基本
Goは関数からerror型を戻すことによりエラーを処理する
関数が期待通りに実行された場合はerrorにはnilが返される
何かがうまくいかない場合はerror型の値が返される
呼び出し側では、errorの戻り値をnilと比較することでチェックし、そのエラーを処理したり独自のエラーを返したりする
code:go
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文の内部にインデントして書かれ、ビジネスロジックはインデントされない。この違いにより、どのコードが主要な処理でどのコードが例外的な状況なのか視覚的に説明できる