エラーを作る
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 を超えています", price, max)プレーンテキスト
価格 2000000 は上限 1000000 を超えていますSprintf と同じ型紙が使えます。違いは、文字列ではなく error を作ることだけです。
実際の開発では、こちらのほうが圧倒的に役に立ちます。「価格が上限を超えています」だけでは、いくらだったのか分からず調査に困ります。
エラー文の書き方
Go には慣習があります。
プレーンテキスト
小文字で始める 句点で終わらない
errors.New("価格が0以下です") 日本語ならこれで問題ない
errors.New("invalid price") 英語なら小文字始まり
errors.New("Invalid price.") 英語では避ける形理由は、エラーが他のエラーの中に埋め込まれることがあるからです。
プレーンテキスト
failed to create item: invalid price途中に大文字や句点が混ざると、文としておかしくなります。日本語で書く場合はあまり気にしなくて済みますが、そういう習慣がある言語だと知っておくと、標準ライブラリのエラー文が読みやすくなります。
定義済みのエラーを持つ
同じエラーを何度も返す場合は、変数にしておく書き方もあります。
Go
var ErrNotFound = errors.New("商品が見つかりません")
func findItem(id int) (int, error) {
return 0, ErrNotFound
}呼び出し側で「このエラーかどうか」を比べられるようになります。
Go
if err == ErrNotFound {
return "見つかりませんでした"
}文字列で比べると、文言を直した瞬間に壊れます。変数で比べるのが定石です。第8章で 404 を返す判断をするときに、この形が出てきます。
要件
- 商品名が空なら
商品名が空ですを返す - 価格が0以下なら
価格が0以下ですを返す - 価格が1000000より大きいなら
価格 N は上限を超えていますを返す(N は実際の価格) - 問題が無ければ
商品名 を登録しましたを返す - 判定は上の順番で行い、最初に見つかった問題を返す
入出力例
registerItem("きのこ図鑑", 1200) → "きのこ図鑑 を登録しました"
registerItem("", 1200) → "商品名が空です"
registerItem("きのこ図鑑", 0) → "価格が0以下です"
registerItem("きのこ図鑑", 2000000) → "価格 2000000 は上限を超えています"
registerItem("", -5) → "商品名が空です"ヒント
編集 ゆめさく編集部