Upgrade to Pro — share decks privately, control downloads, hide ads and more …

標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127...

Avatar for convto convto
September 11, 2026

標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision

Go Conference 2026 で話した内容です
https://gocon.jp/2026/timetable/1264524/

Avatar for convto

convto

September 11, 2026

More Decks by convto

Other Decks in Programming

Transcript

  1. 広く使われるソフトウェアの難しさ Go 互換性ポリシー Goは極力互換性を保つことで、Goで書かれたプログラムが壊れることを避けている Go1 で書かれたコードは将来の Go1 系リリースが登場しても例外を除き引き続き動作する: https://go.dev/doc/go1compat Go1

    の互換性を破壊するような Go2 は永遠にない https://go.dev/blog/compat 利用者への恩恵は非常に大きい が、実装側は公開したAPIの互換に保ち続けるコストを負う © LayerX Inc. 7
  2. 広く使われるソフトウェアの難しさ 例: net/http に残る context 以前の API context パッケージの導入以前、キャンセル制御は個別の仕組みだった その頃の仕組みは今も後方互換として

    net/http に残り続けている より良い仕組みが生まれても、一度公開したものは消せない ref: https://pkg.go.dev/net/[email protected]#CloseNotifier © LayerX Inc. 8
  3. 広く使われるソフトウェアの難しさ FAQ: Why isn't X in the standard library? 標準ライブラリの実装における制約はFAQにも言及がある。

    Go 1 互換性保証の対象 になるため、よりよい API を思いついても過去に公開したもの は修正できない Go のリリーススケジュールに縛られ、バグ修正をすぐユーザーに届けられなくなる ほとんどの新しいコードは標準の外に置くべき(リリースサイクル・互換性についての 意思決定を独立してやれる) ref: https://go.dev/doc/faq#x_in_std © LayerX Inc. 10
  4. uuid を標準に追加する議論の歴史 #23789 proposal: add uuid generator to stdlib (2018-02)

    外部パッケージや独自実装で uuid が作られているので、標準で作ってもいいのではと いう提案 議論ののち Russ Cox が判断材料が不足しているとして却下 I don't think we have enough information about what is needed in the standard library. I think for now the answer is to keep using third-party packages. — rsc, golang/go#23789 クローズ時のコメント ref: https://github.com/golang/go/issues/23789 © LayerX Inc. 14
  5. uuid を標準に追加する議論の歴史 再掲: 標準ライブラリの実装にはさまざまな制約がある Go 1 互換性保証の対象 になるため、よりよい API を思いついても過去に公開したもの

    は修正できない Go のリリーススケジュールに縛られ、バグ修正をすぐユーザーに届けられなくなる ほとんどの新しいコードは標準の外に置くべき(リリースサイクル・互換性についての 意思決定を独立してやれる) ref: https://go.dev/doc/faq#x_in_std © LayerX Inc. これらを打ち消すメリットや普遍性がないと標準には採用されない 15
  6. uuid を標準に追加する議論の歴史 再提案: #62026 uuid: add API to generate and

    parse UUID (2023-08) 2023-08、あらためて uuid の標準ライブラリ追加が提案された これは最終的に accept され Go1.27 で実装された ref: https://github.com/golang/go/issues/62026 2018では判断材料不足としていたが、状況はどう変わったのか © LayerX Inc. 16
  7. 変化① エコシステムでの実績 Go パッケージの被依存数ランキング 順位 パッケージ 依存モジュール数 1 github.com/stretchr/testify 259,237

    2 github.com/google/uuid 104,877 3 golang.org/x/crypto 100,633 4 google.golang.org/grpc 97,228 5 github.com/spf13/cobra 93,062 依存モジュールは 2026-01 時点の proxy.golang.org の内容から分析したよう ref: https://blog.thibaut-rousseau.com/blog/the-most-popular-go-dependency-is/ © LayerX Inc. 17
  8. 変化① エコシステムでの実績 google/uuid がめちゃめちゃ使われてることがわかった google/uuid は Go エコシステムで 2 番目に

    import されるパッケージになっていた golang.org/x/crypto や google.golang.org/grpc よりも多い 多くの利用実績があるため、利用傾向を分析したりすることが可能に ref: https://blog.thibaut-rousseau.com/blog/the-most-popular-go-dependency-is/ これにより何をサポートするか、どのようなAPIがよいか、などの 議論がしやすい状態に © LayerX Inc. 18
  9. 変化② 仕様の成熟 RFC 9562 (2024): UUID 仕様自体もアップデートされた RFC 4122 を置き換える新仕様。v6〜v8

    が追加され、仕様が整理された 「どのバージョンを・どうサポートすべきか」を議論するための土台が整った © LayerX Inc. 19
  10. uuid を標準に追加する議論の歴史 uuid を標準に追加する議論の歴史 2018 年の提案 #23789 は「判断材料の不足」を理由に却下された 5 年後の再提案

    #62026 は accept され、Go 1.27 で実装された 判断を変えた状況の変化は、google/uuid の利用実績と、RFC 9562 による仕様の成熟 © LayerX Inc. 20
  11. 標準で uuid を持つ意義 セキュリティ面の恩恵もちょっとある satori/go.uuid にて、乱数の読み込み処理の不備により 生成される UUID v4 の空間が

    狭まる 脆弱性 (CVE-2021-3538) などが起きた セッション ID などに UUID を使っていたら問題 v4 の安全性は「暗号学的に安全な乱数で埋まっていること」が前提 rand の取り扱いを間違えると、偏りが生まれるなど推測余地のある状態になる このような取り回しのミスは言語仕様をよく知る人間がメンテすれば起きづらい © LayerX Inc. 26
  12. 論点: パッケージ配置 当初案は crypto/uuid で crypto/rand による安全な乱数生成を名前で示そうとした しかし RFC 9562

    には暗号にまつわる語彙がほぼ登場しない また将来、乱数ベースでないバージョンをサポートする可能性もある 最終的にトップレベルの uuid に着地 © LayerX Inc. 32
  13. サポート範囲について: v4 と v7 だけサポート google/uuid の利用統計を分析してサポート範囲を決定 version v4 v1

    v7 その他 利用率 94.17% 4.39% 1.22% 0.22% 判断 サポート ✘ RFC 9562 が新規利用に非推奨 サポート(v1 の後継として推奨) ✘ 利用傾向などを分析した上で、十分利用されるものに絞ってサポート エコシステムで十分な実験がなされたおかげでこのような議論ができた! © LayerX Inc. 33
  14. 補足: v4 と v7 のレイアウトと特徴 v4: ver / var 以外の

    122 bits がすべてランダム random_a 48 bits v7: 先頭 48 bits が UNIX タイムスタンプ(ミリ秒) unix_ts_ms 48 bits ver random_b var 4 12 bits 2 random_c ver rand_a var rand_b 4 12 bits 2 62 bits 62 bits v4: 実質すべてランダムな、推測できない大きな乱数。もっとも広く使われている v7: 先頭がタイムスタンプなので時系列にソートできる。局所性がほしい用途向き © LayerX Inc. 34
  15. 論点: 作成するときの API はどんな形にするか と NewV4 は現在同じ挙動。それでも両方置くのは version を気にせず単に uuid

    が ほしいケースを意識 New 将来より良いデフォルトが現れたら、 New の挙動を変えるなども検討できる NewRandom © LayerX Inc. などの意味のある命名も考えられたが v7 に相当する名前が難しく断念 35
  16. 論点: v7 実装どうするか RFC 9562 では v7 における同一 tick 内の単調性保証の手法を実装者の裁量に委ねている

    前回採番したタイムスタンプをプロセス内に保持し、前回以下なら前回値 +1 を採用 秒単位の大きなクロック逆行時は補正しない(そこまでは保証しない割り切り) 詳細まとめたので気になる方はこちらをどうぞ Go1.27 Release Party の資料 unix_ts_ms 48 bits ver 4 sub-ms ts var 12 bits 2 rand_b(毎回ランダム) 62 bits ms 48 + sub-ms 12 をひとつの 60 bit タイムスタンプとして扱う。rand_b はカウンタに使わない © LayerX Inc. 36
  17. 論点: UUID の中身を覗けるべきか version / timestamp などの抽出 API は提供しない RFC

    9562 の「UUID は不透明な値として扱うべき」という推奨に沿った設計 たとえば v7 だとタイムスタンプなど取り出したくなりがち しかし、のちに v4 も利用するようになったら期待する値が取れなくなる、などありうる v7 のレイアウト unix_ts_ms 48 bits © LayerX Inc. ver 4 rand_a 12 bits var 2 rand_b 62 bits 37
  18. 論点: 時刻を指定して v7 を生成できるべきか 「時刻やオフセットを指定した v7 生成」の要望もあったが 見送り 時系列ソートできることが v7

    の重要な点。任意時刻を作れたりオフセット指定可能に すると、その恩恵の一部が崩れる © LayerX Inc. 38
  19. 論点: Nil と Max は必要か RFC 9562 定義の全ビット 0 /

    全ビット 1 の UUID 当初は入れない意向だった Nil は UUID{} と書けば済むため は uuid.UUID{} より書き手の意図が伝わるという議論があった 一方を採用するなら対称性のためもう一方も採用しよう、となり両方サポート (個人的には使ったことないので不要と思っているが、まあメンテナンスのコストもほぼ なかろうと思うのでメリットの方が多いと判断されたと理解している) uuid.Nil © LayerX Inc. 40