Go 1.27.0が2026年8月19日に正式リリースされた。今回、Go 1.18で型パラメータを導入した際に残った制約の一つが外れた。具体型に定義するメソッドは、レシーバー型の型パラメータに加え、メソッド自身の型パラメータを宣言できる。

ただし、対象は具体型のメソッドに限られる。インターフェースのメソッドは依然として型パラメータを宣言できず、ジェネリックメソッドをリフレクション経由で型指定して呼び出すこともできない。便利な構文を増やしながら、Goの暗黙的なインターフェース実装が抱える実行時ディスパッチの問題には踏み込まない。Go 1.27の設計は、その境界を明示した更新である。

Go 1.27には、埋め込み構造体の昇格フィールドを構造体リテラルで初期化できる変更と、関数型推論の適用範囲を広げる変更も入った。いずれも派手な新機能というより、既存の書き方で発生していた不均一さを減らす作業だ。AI支援でコードを生成する場面でも、価値を測るべきなのは生成器の好みではなく、人間がレビューし、検証し、保守できるコードになるかどうかである。

AD

Rand.Nでメソッド固有の型を受け取れる

Go 1.18は関数と型に型パラメータを導入した。たとえばジェネリック型はメソッドを持てたが、そのメソッドが利用できる型パラメータはレシーバー型から受け取ったものだけだった。メソッドの宣言そのものに、別の型パラメータを増やすことはできなかった。

Go 1.27では、具体型のメソッドならその制約がなくなる。標準ライブラリのmath/rand/v2は、(*Rand).N[Int intType](n Int) Intを例に挙げる。乱数生成器Randをレシーバーに置き、引数と戻り値の整数型をIntとしてメソッド内で宣言する書き方だ。

ここで新しいのは、ジェネリックなNという操作が初めて現れたことではない。同パッケージには以前からパッケージレベルのジェネリック関数Nがあり、Go 1.27はそれをレシーバーに結び付けた形でも表せるようにした。乱数生成器のように状態を持つ値に操作を寄せたいAPIでは、名前空間を分けつつ左から右へ読み下せる。

Go 1.26まで Go 1.27
ジェネリック型のメソッドは、レシーバー型の型パラメータを使えた 具体型のメソッドは、メソッド固有の型パラメータも宣言できる
ジェネリック操作はパッケージ関数として表す場面があった レシーバーに結び付けた操作としても表せる

表の差は、すべてのジェネリック処理をメソッドへ移す理由にはならない。Goの提案では、メソッドが名前空間とチェーン可能な記法を与える点を、この変更の実用上の利点としている。ライブラリ作者は、型の状態に関係する操作か、独立した関数で十分な操作かを従来どおり選ぶことになる。

なお、ジェネリックなレシーバー型をメソッド式として使うときは、型を先に具体化しなければならない。List[string].formatは有効になり得る一方、List.formatは有効ではない。メソッド側の型パラメータが追加されても、レシーバー型を未確定のまま扱えるわけではない。

インターフェースとreflectを変えない理由

Goのインターフェース実装は暗黙的である。ある型が必要なメソッド集合を持てば、その型は宣言なしでインターフェースを満たす。この性質をジェネリックメソッド付きのインターフェースまで拡張すると、実行時の呼び出しでどの型引数の実装を用意すべきかという問題が生じる。

提案#77273は、具体型のレシーバーに対する呼び出しなら静的に解決でき、概念的にはジェネリック関数の呼び出しへ翻訳できると説明する。そこでGo 1.27は、具体型のメソッドだけを対象にした。実行時に無制限の型引数を伴うインターフェース呼び出しを解決する仕組みを先に作る必要がない。

この線引きには、利用者が見落としやすい結果が二つある。第一に、インターフェースのメソッドは型パラメータを宣言できない。第二に、ジェネリックな具体メソッドが、ある一つの具体化で形が合うからといって、非ジェネリックなインターフェースを実装するわけでもない。提案が示す例では、Read[E any]というジェネリックメソッドは、Read[byte]が合いそうに見えてもio.Readerを実装しない。

reflectも同じ範囲外に残る。名前やインデックスで取得したメソッドを呼ぶ前に、リフレクション側にはジェネリックな値や型を具体化する方法が必要になる。しかしreflectにはその機構がないため、ジェネリックメソッドを名前またはインデックスから見つけて呼び出すことはできない。既存のインターフェース駆動の設計や、リフレクションで拡張点を作るコードは、新構文を採用する前にこの違いを確認すべきだ。

AD

2015年から残った構造体リテラルの穴

Go 1.27には、ジェネリックメソッド以外にも言語変更がある。構造体リテラルのキーには、任意の有効なフィールドセレクターを書けるようになった。埋め込み構造体から昇格したフィールドも、外側の構造体を初期化するときに直接指定できる。

この変更の提案#9859は2015年2月12日に起票されていた。従来は、読み出しなら選べる昇格フィールドでも、リテラルでは埋め込み側の構造を明示して初期化する必要があった。フィールドを選択する場面と生成する場面で規則がずれていたのである。

もう一つは、ジェネリック関数を一致する関数型へ代入または変換するときの型推論だ。Go 1.21では推論の範囲が広がったが、直接代入なら推論できても、複合リテラルや型変換、チャネル送信では明示的な型引数が必要になるケースが残っていた。Go 1.27では、対応する関数型への代入または変換が現れるすべての文脈へ対象を広げた。

二つの変更は、短いコードを書くためだけのものではない。読み出し、初期化、代入という近い操作で規則が違えば、利用者は型引数や構造をどこで明示すべきかを覚え分けなければならない。Go 1.27は、既に認めていた操作を同等の文脈へ広げ、記法の例外を減らしている。

AI支援開発では、生成よりレビューの条件を測る

GoogleのGoチームは8月11日、AI支援開発ではコード生成の後に人間がレビュー、検証、保守する工程がボトルネックになると述べた。その説明では、書式が標準化され、抽象化が限定されていることに加え、静的型と互換性、決定的なツール群が、この反復を支える要素に挙げられている。

Go 1.27の新しいメソッド記法について、AIエージェントの精度やレビュー時間、欠陥率を比較した一次資料はない。したがって、ジェネリックメソッドがAI支援を悪化させる、あるいは文脈を劣化させるとは結論づけられない。実際の導入では、変更前後のレビュー所要時間、静的解析の指摘、テスト失敗、保守時の理解コストをチームごとに測る必要がある。

実装面では、互換性の確認も欠かせない。Go 1.27はGo 1互換性の約束を維持し、ほとんどのプログラムは従来どおりコンパイルと実行ができる見込みだ。一方で提案#77273は、import/exportデータ形式と各種ツールを同期させる必要があり、一部のツールは追随まで1〜2リリースを要する可能性に触れていた。

Goツールチームは2026年2月11日、新構文への対応状況を監査するissue #77549を起票した。対象はgoplsとvulncheckから、staticcheckやgolangci-lint、vscode-go、GoLand、Delveまで広い。この一覧は影響を受ける領域を示すが、全ツールの対応完了を意味しない。CIのリンター、IDE、デバッガーを固定しているチームは、Go本体を上げる前に自分たちが使う組み合わせで確認するのが現実的である。

言語以外の更新も検証の材料になる。go teststdversionのvetチェックを既定で実行し、go.modとビルドタグから推定した対象Goバージョンより新しい標準ライブラリのシンボルを報告する。go fixにはatomictypesembedlitslicesbackwardunsafefuncsの四つのmodernizerが加わった。新しい記法を使う場所と、対象バージョンを守る場所を同じ更新で点検できる。

ランタイムでは、80バイト未満の一部の割り当てでコストを最大30%下げる専用ルーチンを導入した。Goチームは、割り当ての多い実プログラムでは全体で約1%の改善を見込む一方、バイナリサイズは約60KB増えるとしている。これは全アプリケーションが30%高速になるという意味ではない。導入判断では、ベンチマークの対象ワークロードとバイナリサイズの許容範囲を分けて見るべきだ。

Go 1.27は、書けるコードを増やす一方で、どこに既存の仕組みを適用しないかも明確にした。具体型のAPIを整えるならジェネリックメソッド、互換性を守るならツールチェーンの組み合わせ、AI支援の効果を語るなら実測が判断材料になる。それぞれを混ぜずに確認することが、今回の更新を安全に使う近道だ。