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

Go Proposal Weekly Digest

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

#54297likely_decline

must: Do

ステータス変更: active likely_decline

要約

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

概要

Go標準ライブラリに must.Do のような汎用的な「エラーが非nilならpanicする」ヘルパー関数を追加するproposal。元々は url.MustParse という具体的な要望から始まり、regexp.MustCompiletemplate.Must のような既存パターンを一般化する must パッケージの提案へと発展した。

ステータス変更

activelikely_decline
Go 1.27でジェネリックメソッド(#77273)が実現し testing.T.Must[T any] が技術的に可能になったことを受けて再度アクティブに審査されたが、最終的に「単一の極めて小さな関数のためだけに新パッケージを追加するのは適切でない」「testing.T.Must はテストの意図をぼかす」という合意に至り、likely declineとなった。代わりに元の具体的な要望である url.MustParse が別issue #79946として切り出されてアクティブキューに追加された。

技術的背景

現状の問題点

Goには regexp.MustCompiletemplate.Mustnetip.MustParseAddr など、「エラーが発生したらpanicする」関数がパッケージ固有に散在している。しかし汎用的なものがないため、各コードベースで同じようなヘルパーが繰り返し書かれている。

// 各プロジェクトで独自に実装されているパターン
func must[T any](v T, err error) T {
    if err != nil {
        panic(err)
    }
    return v
}
// 使用例:グローバル変数の初期化
var target = must(url.Parse("https://example.com"))

Tailscaleは tailscale.com/util/must、Ridgeは github.com/ridge/must など、多くの著名なコードベースが独自実装を持っている。

提案された解決策

標準ライブラリに must パッケージを追加し、以下のような関数を提供する:

// must.Get: (T, error) → T、エラー時はpanic
func Get[T any](v T, err error) T
// must.Do: error → void、エラー時はpanic
func Do(err error)

加えて testing.T.Must[T any](v T, err error) T をテスト用に追加する案も議論された。

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

コード例

// Before: 従来の書き方(ボイラープレートが多い)
u, err := url.Parse("https://example.com/api")
if err != nil {
    panic(err) // 定数URLなので実際には発生しない
}
var baseURL = u
// After: must.Get を使った書き方
var baseURL = must.Get(url.Parse("https://example.com/api"))

想定ユースケース:

  1. init 関数やパッケージレベル変数の初期化(URLやregexpなど定数値のパース)
  2. 簡易スクリプトやCLIツールでのエラー処理省略
  3. テストコードでの前提条件セットアップ(テスト対象外の処理)

議論のハイライト

  • 「小さすぎる」問題: 単一の極めてシンプルな関数のためだけに新パッケージを標準ライブラリに追加することへの抵抗感が根強かった。github.com/search で5,900件以上の独自実装が確認されたにもかかわらず、「標準ライブラリに入れる必要性」の合意が得られなかった
  • testing.T.Must への懸念: adonovan が「これが追加されると、テストが失敗した際に有用なコンテキストを添えるという活性化エネルギーが上がる」と指摘。「このエラーは起きないはず」と「このエラーが起きないことをテストしている」の区別が曖昧になる
  • must.Do の誤用リスク: must.Do(process()) のように main 関数内でエラー処理代わりに使われることへの懸念。ianlancetaylor は「エラーハンドリング機構として使われるのは非常に残念」と発言
  • ジェネリックメソッド待ち: #77273(ジェネリックメソッド)の受理により testing.T.Must[T any] が実現可能になったが、審査再開後も testing.T.Must 自体への懸念は解消されなかった
  • 元のプロポーザルへの回帰: 最終的にneilが「元々は url.MustParse の提案だった」と原点回帰を促し、より限定的な #79946 として再検討が始まった

関連リンク