uuid: rename Nil to Zero
要約
概要
Go標準ライブラリへのuuidパッケージ追加(Issue #62026)で承認されたuuid.Nil()関数について、その名称をuuid.Zero()に変更することを求めるプロポーザルです。最終的にこの改名提案は却下され、Nilという名前が維持されることになりました。
ステータス変更
likely_decline → declined
プロポーザルレビューグループは2026年4月15日の時点でNil維持を支持する方向を示し、4月22日に正式に却下を決定しました。コンセンサスに変化がなかったため、aclementsが代表して「No change in consensus, so declined」とコメントしています。
技術的背景
現状の問題点
このプロポーザルが提起された背景には、Go言語における「nil」の意味論と、UUID仕様における「Nil UUID」という用語の衝突があります。
Goにおいてnilはポインタ、インタフェース、マップ、スライス、チャネルに対して有効な値です。しかしUUID型は[16]byteという値型(配列)であり、Goの意味論では絶対にnilになれません。この点でuuid.Nil()というAPIは、開発者に誤った印象を与える可能性がある、という懸念が提起されました。
// 問題: UUID は [16]byte であり Go の nil にはなれないが
// 関数名が uuid.Nil() だと nilポインタを返すかのような誤解を招く
u := uuid.Nil() // 実際は UUID{} と等価
// GoのnilはUUIDには使えない(コンパイルエラー)
var u uuid.UUID = nil // コンパイルエラー
提案された解決策
@rogpeppe(#62026 のコメント)がuuid.Nil()をuuid.Zero()に改名することを提案しました。Go標準ライブラリではtime.Time.IsZero()やimage.ZR(deprecated)のように「zero」という語でゼロ値を表す慣習があり、これに倣うべきという主張です。
// 提案: Zero() に改名
// Zero returns the zero UUID (00000000-0000-0000-0000-000000000000),
// also known as the Nil UUID in RFC 9562.
func Zero() UUID { return UUID{} }
これによって何ができるようになるか
このプロポーザルが却下されたため、最終的にuuid.Nil()という名前のまま維持されます。
コード例
// 現行API(維持決定): uuid.Nil()
u := uuid.Nil()
if u == uuid.Nil() {
fmt.Println("zero UUID")
}
// 代替案(却下): uuid.Zero()
u := uuid.Zero()
if u == uuid.Zero() {
fmt.Println("zero UUID")
}
// 最も単純な方法(どちらにせよ使用可能)
var u uuid.UUID // u == uuid.UUID{} が Nil UUID
if u == (uuid.UUID{}) {
fmt.Println("zero UUID")
}
議論のハイライト
- RFC 9562の用語との整合性: RFC 9562が"Nil UUID"という用語を定義しており、
github.com/google/uuidやgofrs/uuidなど既存の主要パッケージもvar Nil UUIDという識別子を持つ。スペックが名前を定義している場合はその名前を使うべきという立場が支持された。 - 型システムによる保護:
uuid.Nil()という名前が誤解を招くとしても、GoのUUID型([16]byte)にnilを代入しようとすればコンパイルエラーになるため、混乱の実害は限定的という@neildの指摘。 Zero()の存在意義への疑問:@neildは「uuid.Zero()はuuid.UUID{}より何が優れているのか?」と問い、互換性維持の理由がなければそもそも何も追加しなくてよいという見解を示した。これは採用への積極的理由が弱まったことを意味する。IsZero()は不要:@neildはUUID.IsZero()メソッドの追加も否定。IsZero()はゼロ値との単純な比較では不十分な型(例:time.Timeはロケーションを無視)に対してのみ意味があり、UUIDでは== uuid.UUID{}で十分。- プロポーザルチェーンの逆転:
@neildは採用経緯(「uuid.UUID{}で十分 → google/uuidとの互換性のためNilを追加 → varよりfuncが安全 → Zeroの方がGoらしい」)を整理し、途中で当初の採用理由(互換性)が失われており、名前変更後のZero()にはそもそも正当化根拠がないと論じた。