構造体とインターフェース
Go Error Handling: errors.Is and errors.As
Errors are values in Go. Return them, add context with %w, and check them the right way.
学べること
- Returning errors
- Wrapping with %w
- errors.Is and errors.As
findUser(id)
findUser(1)"Ada", nilfindUser(7)wrapped ErrNotFoundfindUser(-1)*ValidationErrorCheck the error, then continue
Go has no exceptions for ordinary failures. A function that can fail returns an error as its last value, and the caller checks whether it is nil.
ErrNotFound is a fixed error value that callers can compare against. %w wraps it with more context, and errors.Is still finds it inside the wrapped error. ValidationError is an error type with its own data, and errors.As extracts it.
重要なポイント
- nil means success.
- %w wraps an error with more context.
errors.Isfinds an error inside a wrapped one.
実行できる Go のサンプル
Go
main.go
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("user not found")
type ValidationError struct {
Field string
}
func (e *ValidationError) Error() string {
return "invalid " + e.Field
}
func findUser(id int) (string, error) {
if id <= 0 {
return "", &ValidationError{Field: "id"}
}
if id != 1 {
return "", fmt.Errorf("find user %d: %w", id, ErrNotFound)
}
return "Ada", nil
}
func main() {
for _, id := range []int{1, 7, -1} {
name, err := findUser(id)
var validation *ValidationError
switch {
case err == nil:
fmt.Println("found", name)
case errors.Is(err, ErrNotFound):
fmt.Println("missing:", err)
case errors.As(err, &validation):
fmt.Println("bad input:", validation.Field)
}
}
}
found Ada
missing: find user 7: user not found
bad input: id練習
サンプルをオンラインコンパイラーで開き、値を変えたり行を追加したりして、実行する前に出力を予想してみましょう。次に、わざとコードを壊してコンパイラーのメッセージを読んでみてください。
このレッスンを終えましたか?
学習済みにすると進み具合を記録できます。
進み具合はこのブラウザーに保存されています ログインすると、どのデバイスでも引き継げます。
チャレンジで練習する
このレッスンの内容を使って実際の問題を解きましょう。各チャレンジはブラウザで動き、すぐにテストされ、AI のレビューも受けられます。
- 最初の無効な年齢 入力された年齢を検証し、プログラムがクラッシュする代わりに最初の不正な入力位置を報告します。 簡単
- 有効な数だけを合計する 整数の項目だけを合計し、それ以外は try/except で不正入力を扱うように無視します。 簡単