エラーを作る
errors.New で作る
Go
import "errors"
return errors.New("人数が0以下です")渡した文字列が、そのエラーの理由になります。取り出すときは Error() を呼びます。
Go
err := errors.New("人数が0以下です")
fmt.Println(err.Error()) // 人数が0以下ですfmt.Println(err) と書いても同じ文字が出ます。%v で埋め込むこともできます。
fmt.Errorf で値を混ぜる
理由に具体的な値を入れたいときは fmt.Errorf です。
Go
return fmt.Errorf("人数 %d は定員 %d を超えています", people, capacity)人数 25 は定員 20 を超えていますSprintf と同じ型紙が使えます。違いは、文字列ではなく error を作ることだけです。
実際の開発では、こちらのほうが圧倒的に役に立ちます。「人数が定員を超えています」だけでは、何人だったのか分からず調査に困ります。
エラー文の書き方
Go には慣習があります。
小文字で始める 句点で終わらない
errors.New("人数が0以下です") 日本語ならこれで問題ない
errors.New("invalid count") 英語なら小文字始まり
errors.New("Invalid count.") 英語では避ける形理由は、エラーが他のエラーの中に埋め込まれることがあるからです。
failed to reserve room: invalid count途中に大文字や句点が混ざると、文としておかしくなります。日本語で書く場合はあまり気にしなくて済みますが、そういう習慣がある言語だと知っておくと、標準ライブラリのエラー文が読みやすくなります。
定義済みのエラーを持つ
同じエラーを何度も返す場合は、変数にしておく書き方もあります。
Go
var ErrNotFound = errors.New("部屋が見つかりません")
func findRoom(id int) (int, error) {
return 0, ErrNotFound
}呼び出し側で「このエラーかどうか」を比べられるようになります。
Go
if err == ErrNotFound {
return "見つかりませんでした"
}文字列で比べると、文言を直した瞬間に壊れます。変数で比べるのが定石です。第8章で 404 を返す判断をするときに、この形が出てきます。
問題がなければ nil
戻り値が error の関数は、問題がないときに return nil と書きます。エラーの理由が必要な場合には errors.New や fmt.Errorf を返し、成功を空文字のエラーで表さないようにします。
演習の unfinishedError() は、未完成のひな形でも実行できるように仮のエラーを返す補助関数です。補助関数と呼び出し側は変更せず、検証する関数の4つの仮の return を書き換えます。
要件
- 商品名が空なら
errors.Newで商品名が空ですのエラーを返す - 価格が0以下なら
errors.Newで価格が0以下ですのエラーを返す - 価格が1000000より大きいなら
fmt.Errorfで価格 N は上限を超えていますのエラーを返す。N は実際の価格 - 問題がなければ
nilを返す - 用意済みの判定条件と順番、補助関数、呼び出し側は変更しない