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

Go Proposal Weekly Digest

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

#54297declined

must: Do

ステータス変更: likely_decline declined

要約

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

概要

must.Do は、エラーを返す関数の結果をパニックで包む汎用ヘルパー関数(func Do[T any](v T, err error) T)を標準ライブラリに追加するproposalです。regexp.MustCompiletemplate.Must に倣い、グローバル変数の初期化やスクリプト的なコードでのエラー処理の定型文を削減することを目的としていました。

ステータス変更

likely_declinedeclined
2026年6月25日の提案レビュー会議で、コンセンサスに変化がなかったとして正式にdeclinedとなりました。懸念の核心は「attractive nuisance(魅力的だが危険な罠)」という概念で、標準ライブラリに加えることでエコシステム規模での誤用が広がるリスクが利便性を上回ると判断されたためです。

技術的背景

現状の問題点

regexp.MustCompilenetip.MustParseAddr のように「パニックで失敗する」パターンは既にGoに存在しますが、汎用版がないため各コードベースで同様のヘルパーが重複して実装されています。

// 現状: グローバル変数の初期化でよく見られる定型文
var target *url.URL
func init() {
    var err error
    target, err = url.Parse("https://example.com/api")
    if err != nil {
        panic(err)
    }
}
// あるいはサードパーティ製ヘルパーを使う(tailscale, ridge等)
var target = must.Get(url.Parse("https://example.com/api"))

提案された解決策

新パッケージ must に以下の関数群を追加する案でした。

package must
// Do はエラーがnilでない場合にパニックする
func Do(err error)
// Get はエラーがnilでない場合にパニックし、値を返す
func Get[T any](v T, err error) T
// Get2 は2つの値を返す関数に対応
func Get2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2)

議論の途中では、errors.Musttesting.T.Must(ジェネリックメソッドが実現した場合)、あるいは url.MustParse 単体追加など、様々な代替案が検討されました。

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

実現していれば、以下のような場面での記述が簡潔になるはずでした。

  • グローバル変数として定数URLを初期化する
  • json.Marshal など「構造体が変わらない限り失敗しない」処理のラップ
  • 簡易CLIツールやスクリプトでのdo-or-die的エラー処理

コード例

// Before: 定型的な初期化コード
var apiBase *url.URL
func init() {
    var err error
    apiBase, err = url.Parse("https://api.example.com")
    if err != nil {
        panic(err)
    }
}
// After: 提案されたAPIを使った書き方(実現せず)
import "must"
var apiBase = must.Get(url.Parse("https://api.example.com"))

議論のハイライト

  • 「attractive nuisance」問題: must.Do(err) を通常のエラーハンドリングとして乱用するリスクを複数のコアメンバーが指摘。aclements は「既存の各パッケージの *Must API ですら誤用による障害が発生している」と言及し、汎用版はエコシステム規模でより大きなリスクになると結論しました。
  • testing.T.Must の検討と棄却: ジェネリックメソッド(#77273)が受け入れられたことで (*testing.T).Must[T any] が技術的に可能になりましたが、テストの前提条件(「これは失敗しないはず」)と検証条件(「これが失敗しないことをテストしている」)の区別を曖昧にするとして否定的な見解が多く出ました。
  • 単一関数のためだけのパッケージ: 標準ライブラリに関数1つだけのパッケージを追加することへの抵抗感が根強く、errors.Must のような既存パッケージへの追加案も命名の意味論的なわかりにくさから支持を得られませんでした。
  • 提案の分割と url.MustParse: 議論の末、元々のきっかけであった url.MustParse の追加を別issue(#79946)として分割して検討することになりました。2026年6月24日時点でこちらは「likely accept」となっています。
  • 長期保留を経たdecline: 2026年1月にはジェネリックメソッドの動向待ちでいったんholdとなり、約5ヶ月後にジェネリックメソッドが受け入れられた後に議論が再開。しかし最終的にコンセンサスは変わらずdeclinedとなりました。

関連リンク