タラバガニー設計局stalins.clubNOTE/notes/type-param-retrofit-is-breaking

既存メソッドへの型パラメータ後付けは破壊的変更

ジェネリクスメソッド (Go 1.27) が入ったからといって、既存の any を使ったメソッドを一斉に型パラメータ付きへ書き換えられるわけではない。それを示したのが #80120 (2026-06-23 提出、同日 duplicate クローズ) である。

提案は x/sync/singleflightGroup.Do(key, func() (any, error))Do[T any](key, func() (T, error)) に変えようというものだった。一見すると型安全になるだけの改善に見えるが、nicholashusin の指摘が本質を突いている。

_ = oldG.Do  // OK
_ = newG.Do  // Compile error (generic method のメソッド値は取れない)

ジェネリクスメソッドはメソッド値・メソッド式を取れない (レシーバの型を先に instantiate する必要があり、レシーバが未確定のままメソッドだけを値として取り出せないため)。つまり any[T any] に置き換えるリファクタは、それだけで既存 API に対して非互換になる。メソッド値を取っている利用者のコードがコンパイルエラーになるからだ。

提案者は「言語の制限が理由でそうなっていた API なのだから、型安全の利得が互換性コストを上回る」と食い下がったが、そのまま閉じられている。

これは #77273 のようにゼロから設計する新規 API の話とは別の文脈である。「ジェネリクスメソッドが入ったので既存の any API を一斉に畳めます」という単純な話ではなく、メソッド化はそもそも自由に適用できる変更ではない。素直に使えるのは新規 API か、まだ利用者のいない API に限られる。tanukirpc の RouteWithTransformerRouteWithTransformer がメソッド化を検討できているのも、既存利用者がまだ広がっていない段階だからという側面がある。

なお AI に API を使わせたのは godoc だけだった の実験結果 (「メソッド化しても AI の API 選択は変わらない、効いたのは godoc だけだった」) とは別方向の話で、こちらは「メソッド化への期待に水を差す」という位置づけになる。ジェネリクスメソッドの導入は API の見せ方の選択肢を増やしたが、既存 API の書き換えを正当化する理由にはならない。

出典

  • #80120
  • Go Release Party 1.27 の発表資料リポジトリ issues.md §3
  • 同リポジトリ memo.md

▸ ノート一覧に戻る