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

Go Proposal Weekly Digest

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

#79946likely_accept

net/url: MustParse

ステータス変更: active likely_accept

要約

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

概要

net/url パッケージに url.MustParse 関数を追加する提案。パース失敗時にパニックする Must バリアントを標準ライブラリに追加することで、コードベース内で各自が実装している同様の関数を置き換える。

ステータス変更

activelikely_accept
2026年6月24日のProposal Review Meeting(@adonovan, @bradfitz, @cherrymui, @griesemer, @ianlancetaylor, @neild, @rolandshoemaker 参加)にて likely accept と判定。より汎用的な must.Do 系の提案(#54297)が likely decline となった同日、この限定的な提案は承認路線に乗った。

技術的背景

現状の問題点

url.Parse はエラーを返すため、パッケージレベルのグローバル変数でURLを定数として保持したい場合に冗長なボイラープレートが必要となる。

// 現状:複数行のボイラープレートが必要
var baseURL *url.URL
func init() {
    var err error
    baseURL, err = url.Parse("https://example.com/api/v1")
    if err != nil {
        panic(err) // URLが固定文字列なら失敗しないと分かっていても...
    }
}
// または、各コードベースが独自のMustParseを実装
func MustParseURL(s string) *url.URL {
    u, err := url.Parse(s)
    if err != nil {
        panic(err)
    }
    return u
}

Sourcegraphの公開リポジトリ検索によると、func.*Must.*Parse.*\*url\.URL パターンに一致する独自実装が多数存在することが確認されている。

提案された解決策

// net/url パッケージに追加される関数
func MustParse(rawURL string) *URL {
    u, err := Parse(rawURL)
    if err != nil {
        panic(err)
    }
    return u
}

netip.MustParseAddrregexp.MustCompiletemplate.Mustuuid.MustParse 等の既存パターンと一貫した命名規則に従う。

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

固定URLを使う初期化コードが簡潔に書けるようになる。

コード例

// Before: 独自のMustParseURLを定義するか、init()でエラー処理が必要
var apiEndpoint *url.URL
func init() {
    var err error
    apiEndpoint, err = url.Parse("https://api.example.com/v2")
    if err != nil {
        panic(err)
    }
}
// After: url.MustParse を直接使用
var apiEndpoint = url.MustParse("https://api.example.com/v2")
// HTTPリバースプロキシの設定など
proxy := &httputil.ReverseProxy{
    Director: func(req *http.Request) {
        req.URL = url.MustParse("https://backend.internal/")
    },
}
// テストコード内での定数URL
var testBase = url.MustParse("https://example.com/test")

議論のハイライト

  • #54297(must: Do)からの分離: 元々 url.MustParse の提案として始まった #54297 は汎用的な must.Do の議論に拡大したが、url.MustParse 単体は「反論の余地がない(unobjectionable)」という評価が早い段階から存在していた(@adonovan、2025年10月)。
  • must.Do 提案との決別: 汎用 must.Do は「小さな関数1つだけのためにパッケージを新設するのは過剰」「ecosystem規模での誤用リスクが高い」として likely decline となった同じ会議で、この限定的な提案は承認路線に入った。
  • 並行性(Parallelism)の論拠: regexp.MustCompilenetip.MustParseAddr などの既存 Must バリアントとの一貫性を保つことが主要な承認理由の一つ。コアチームも「他パッケージとの並行性(parallelism)を保つために追加すべき」という意見を重視した。
  • 実際の使用ケース: httputil.ReverseProxy 設定、パッケージレベルのURL定数、固定文字列を引数とする url.Parse の呼び出しなど、入力が決定論的で失敗し得ないと分かっているケースが対象。
  • 汎用 must ライブラリとの関係: Tailscaleの must.Get[T any](v T, err error) T(@bradfitz提案)など多数のサードパーティ実装が存在するが、std入りは見送られた。一方 url.MustParse のような個別 API は引き続き追加する方針が示された。

関連リンク