導入部:エラーハンドリングの問題

if err != nilのテストは非常に普遍的で、残りのコードを圧倒することがあります。これは通常、多くのAPI呼び出しを行い、エラー処理が初歩的で単に返すだけのプログラムで起こります。一部のプログラムは以下のようなコードになってしまいます:

func printSum(a, b string) error {
    x, err := strconv.Atoi(a)
    if err != nil {
        return err
    }
    y, err := strconv.Atoi(b)
    if err != nil {
        return err
    }
    fmt.Println("result:", x + y)
    return nil
}

この関数本体の10行のコードのうち、実際の作業をしているように見えるのは4行(呼び出しと最後の2行)だけです。残りの6行はノイズのように感じられます。この冗長性は現実的であり、エラーハンドリングに関する苦情が何年間にもわたって年次ユーザー調査でトップになっているのも当然です。(しばらくの間、ジェネリクスの欠如がエラーハンドリングに関する苦情を上回っていましたが、Goがジェネリクスをサポートするようになった今、エラーハンドリングが再びトップに戻っています。)

Goチームはコミュニティのフィードバックを真剣に受け止めており、何年もの間、Goコミュニティからの入力と共に、この問題の解決策を見つけようと試みてきました。

問題の本質

エラーハンドリングの冗長性は、特に以下のような場合に顕著になります:

  1. 連続したAPI呼び出し: 複数の関数を順次呼び出し、それぞれがエラーを返す可能性がある場合
  2. 単純なエラー伝播: エラーが発生した場合に、単純にそのエラーを上位の関数に返すだけの場合
  3. ファイルや構成の読み込み: 初期化処理で多くのエラーチェックが必要な場合

これらの状況では、if err != nil { return err }パターンが頻繁に現れ、実際のビジネスロジックがエラーチェックのコードに埋もれてしまいます。