メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

#21111declined

testing: allow examples to return an error

ステータス変更: active declined

要約

AIによる要約であり、誤りを含む場合があります。

概要

testing パッケージのExample関数に error の返り値を許可する提案です。現在、Example関数は戻り値なしの関数シグネチャのみが認められていますが、エラーハンドリングを含む現実的なコード例を記述する際にボイラープレートが増えてしまう問題を解消することを目的としていました。

ステータス変更

activedeclined
2026年6月10日の提案レビュー会議で「コンセンサスに変化なし」として declined(却下) されました。同会議では類似提案の #79808(任意のシグネチャを持つExample関数を許可する提案)がより汎用的なアプローチとして active に移行しており、本提案はそちらに議論を集約する形で閉じられています。

技術的背景

現状の問題点

Go の Example 関数は現在 func ExampleXxx() のように戻り値を持てないため、エラーを返す可能性のある関数を呼び出す際に paniclog.Fatal、もしくは無視するしかありません。これにより実際のプロダクションコードとは異なるパターンを例示することになり、例として不適切または誤解を招く可能性があります。
標準ライブラリにも log.Fataldefer を組み合わせるという意味的に誤ったコード例が存在します(os.CreateTemp の例など)。これは log.Fatalos.Exit を呼ぶため defer が実行されないためです。

提案された解決策

Example関数が error を返すことを許可する。// Output: コメントを持ち error を返す関数は go test により実行され、非nilのエラーを返した場合はテスト失敗とする、というものでした。

これによって何ができるようになるか

paniclog.Fatal を使わず、実際のコードに近いエラーハンドリングを含む例示が可能になる想定でした。

コード例

// Before: 従来の書き方(ワークアラウンド)
func ExampleWriteTempFile() {
    example := func() (err error) {
        filename, cleanup, err := WriteTempFile("", "example-*", []byte("example"))
        if err != nil {
            return err
        }
        defer cleanup(&err)
        fmt.Printf("Temporary example file name: %s\n", filename)
        return nil
    }
    err := example()
    if err != nil {
        panic(err)
    }
    fmt.Println("no error")
    // Output: no error
}
// After: 提案された書き方(error を返す)
func ExampleWriteTempFile() error {
    filename, cleanup, err := WriteTempFile("", "example-*", []byte("example"))
    if err != nil {
        return err
    }
    defer cleanup(&err)
    fmt.Printf("Temporary example file name: %s\n", filename)
    return nil
    // Output: ...
}

議論のハイライト

  • 2018年に一時停止: rsc がエラーハンドリングの言語変更(Go 2 エラーハンドリング提案)と関連するとして Proposal-Hold ラベルを付けて保留。その後、Go 2のエラーハンドリング構文変更が無期限延期となったことで、2025年末に adonovan がホールドを解除した。
  • go doc での表示問題: neild が、Example関数をドキュメントとして表示する際 func main() に変換する仕組みとの整合性に懸念を示した。error を返す関数を main に変換できないため、表示方法の再設計が必要になることが指摘された。
  • #64993 との比較: aclements が「Example関数にerrorを返すことと、testing.T を受け取ることを両方受け入れるのは整合性の観点で奇妙」と述べ、いずれか一方を選ぶべきとした。rogpeppe(提案者)はコピー&ペースト可能性の観点から本提案を優れていると主張した。
  • より汎用的な代替提案 #79808 の登場: neild が提案した #79808 は「任意のシグネチャを持つExample関数をgo docで表示可能にする(ただしtestingパッケージは実行しない)」という汎用的なアプローチで、レビューグループはこちらを支持する方向へ傾いた。
  • 本提案の // Output: コメントとの相互作用: apparentlymart#79808 では // Output: コメントによる出力検証の仕組みを利用できなくなる可能性を指摘し、#79808 のスレッドで議論を継続するよう aclements に促した。

関連リンク