ProgrammingGo開発者

Goにおけるエラー(errors)の処理の仕組み:どのようなエラー処理のアプローチがあり、なぜエラーをスローするのではなく返すのが一般的で、カスタムエラータイプをどのように実装するか?

Hintsage AIアシスタントで面接を突破

回答。

Goでは、関数から型errorの値を返す標準的なエラー処理のアプローチがあります。例外のある言語とは異なり、Goでは例外(panic, recover)は真に例外的な状況にのみ使用されます。ビジネスロジックには通常のエラーを使用する必要があります。

古典的な方法:

func doSomething() error { // ... return nil // または errors.New("some error") } err := doSomething() if err != nil { // エラー処理 }

より詳細な分析のために、カスタムエラータイプを作成することができます:

type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}

特定のエラーを確認する一般的な方法:

if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // 404エラー処理 }

トリックの質問。

Goでエラーをnilと比較することはできますか?

回答: はい、エラーがないかを確認するために可能で必要です。しかし、注意が必要です:エラーがラップされたり、構造体内部にnilを含むエラーが作成されている場合、比較が誤っている可能性があります。例えば:

var err error = (*MyError)(nil) fmt.Println(err == nil) // false!

インターフェイスはその型がnilでない限りnilと等しくないため、内部がnilでも同様です。

テーマの細かい違いに対する実際のエラーの例。


逸話

マイクロサービスはnilとの比較を通じてエラーをログしていました。開発者の一人が、(*MyError)(nil)のような型付きエラーを返したところ、これがnilに等しくないことに気付かず、エラー処理が機能しなくなり、多くの誤報告がメトリクスに影響を及ぼしました。


逸話

プロジェクトではエラーをチェーンで渡す代わりに、すべてのエラーについてpanicを使用し、これが「クリーンな」方法だと考えていました。これにより、ユーザーの不正な入力ごとにアプリケーションがクラッシュすることになりました。というのも、panic/recoverはストリームビジネスロジックに適していないからです。


逸話

エラーがfmt.Errorf("some: %w", err)を使用して数回ラップされ、特定のエラータイプを確認するときに通常の比較を行い、errors.Iserrors.Asを使用せずに行われました。これにより、ビジネスロジックはカスタムエラータイプに反応しなくなり、ラップされたエラーの内部にそれらが実際に存在しているにもかかわらずです。