7 ポイント 投稿者 GN⁺ 2026-02-18 | 1件のコメント | WhatsAppで共有
  • Go 1.26 では、全面的に書き直された go fix コマンドが導入され、最新の言語機能やライブラリ機能を活用してコードを自動的に改善できる
  • このツールは 数十種類のアナライザ analyzer によってコードパターンを検出し、minmaxrangeintstringscut などさまざまな モダナイザー modernizer を適用して、反復的または古いコードを最新の形へ変換する
  • 新機能である new(expr) のサポートのために、newexpr アナライザが追加され、newInt のようなヘルパー関数を自動的に単純化できる
  • go fix複数回実行すると相乗効果を発揮し、異なるアナライザが連続して改善を提案でき、競合時には自動マージや不要な import の削除機能も含む
  • Go チームは今後、Self-service 分析パラダイムを通じて、開発者が独自 API 向けのモダナイザーを定義して配布できるように拡張する計画

go fix コマンドの概要

  • Go 1.26 で go fix全面的に再実装され、コードベースを最新の Go スタイルへ自動変換する機能を提供
    • go fix ./... コマンドで現在のディレクトリ以下のすべてのパッケージを修正
    • -diff オプションで変更内容を事前に確認可能
  • 登録済みアナライザの一覧は go tool fix help で確認でき、anyforvarmapsloopminmax など多様な変換ルールを含む
  • 特定のアナライザだけを実行するには -any のようなフラグを使い、除外するには -any=false を指定
  • プラットフォームごとのコード差異を考慮して、GOOSGOARCH の組み合わせごとに複数回実行可能

Modernizers — コードモダナイズツール

  • Go 1.18 以降、ジェネリクスの導入によってコードを単純化できる可能性が大きくなった
    • 例: maps.Keys による map キー収集、strings.Cut による文字列分割
  • LLM ベースのコード生成ツールが古いパターンを維持してしまう問題を解決するため、最新の Go イディオムを反映したオープンソースコード更新の必要性を強調
  • go fixgopls に含まれるモダナイザーは、コードの可読性と学習効果を高める
  • モダナイザーの例:
    • minmax: if 文を min / max 関数に置き換える
    • rangeint: 3 項 for 文を range-over-int に変換
    • stringscut: strings.Index ベースのコードを strings.Cut で単純化

Go 1.26 の new(expr) 機能

  • new 関数が 値引数を受け取れるように拡張され、new("go1.26") の形で初期化可能
  • newexpr アナライザは newInt のようなヘルパー関数を見つけて return new(x) に単純化し、呼び出し側を new(expr) に置き換える
  • 最小 Go バージョン要件(例: go 1.26 ディレクティブ)を満たす場合にのみ適用
  • $ go fix -newexpr ./... コマンドでコードベース全体に適用可能
  • 使用後に不要になったヘルパー関数は deadcode ツールで特定可能

相乗効果と競合処理

  • 1 回の修正が別の修正機会を生む 相乗効果がある
    • 例: minmax 適用後に追加の変換提案が生まれる
    • stringsbuilderfmt.Fprintf へと続く連続最適化も可能
  • go fix3-way merge アルゴリズムで修正競合を自動マージする
    • 構文上の競合がある場合はその修正をスキップし、警告を表示
    • 意味的な競合(例: 変数削除、未使用 import)は手動調整が必要
    • 不要な import は自動削除

Go 分析フレームワークとの統合

  • go vetgo fix共通の分析フレームワークを共有するよう統合
    • vet はエラー検出重視、fix は安全な自動修正重視
  • アナライザは unitcheckermulticheckergoplsstaticcheckTricorder などさまざまなドライバで実行可能
  • fact システムにより、パッケージ間で情報共有が可能
    • 例: log.Printffmt.Printf のラッパーであると推論できる
  • gopls はリアルタイム診断と自動修正提案機能を提供

分析インフラの改善

  • inspector パッケージの拡張により AST 探索の効率が向上し、Cursor 型で上下左右への探索をサポート
  • typeindex による関数呼び出しインデックス化で、分析速度が最大 1000 倍向上
  • その他の改善点:
    • 標準ライブラリの 依存グラフを提供
    • ファイルごとの Go バージョンクエリをサポート
    • リファクタリングプリミティブの拡充により、コメントアウトなど安全なコード修正が可能
  • 一部のモダナイザーは微妙な挙動変化のため除外された(append([]string{}, slice...)slices.Clone(slice) の事例)
  • 今後は パターンマッチングエンジン自動テストハーネス正確な修正演算子ライブラリを開発予定

Self-service パラダイム

  • Go 1.26 から Self-service 分析モデルの導入を予告
    • 開発者が独自 API 向けモダナイザーを定義して配布可能
    • 集中承認手続きなしで、プロジェクトレベルで実行可能
  • 第一段階として、アノテーション駆動インライナー Annotation-driven inliner 機能がプレビューとして含まれる
  • 今後の計画:
    • 動的ロードによるユーザー定義アナライザの実行(go fix または gopls 内)
    • 制御フローベースのチェック一般化。例: 「open の後に close」、「lock の後に unlock」などの不変条件を検証
  • 目標は、保守効率の向上と最新 Go 機能の迅速な導入支援

1件のコメント

 
GN⁺ 2026-02-18
Hacker Newsの意見
  • 2024年末にLLMコードアシスタントが急速に普及したとき、こうしたツールが学習データ中の既存のGoコードスタイルをそのまま再現する傾向があるのは興味深かった
    最新の構文を使うよう指示しても無視したり、存在しないとまで否定することさえあった
    今後のモデルが最新のGo 1.25イディオムを反映するには、オープンソースコード全体がそのスタイルへ更新される必要がある

    • PHPでも以前、Stack Overflowの古い助言(例: magic_quotes)を整理しようとする試みがあった
      しかしLLMは一度誤ったデータが入ると修正がほとんど不可能だ
      モデルがどんな根拠で結論を出したのか追跡しづらく、次世代モデルで修正されることを願うしかない
    • LLMが生成するGoの並行処理コードは特に危険だ
      単純に見えるのでレビューを通過するが、実際にはエラー処理やエッジケースが抜け落ちている
      レビュー後に再びLLMへ入れると、見た目には修正されたコードが出てくるものの、その中にデータレースデッドロックが生じる
      ほぼすべてのモデルで繰り返される問題だ
    • 私もこうした問題をよく経験した
      Goは後方互換性が高いのでコンパイルは通るが、コードスタイルがあまりにも違ってしまう
      PythonではAPI変更によって実際の互換性破壊が起きる
      それでもGoは言語の安定性と標準ライブラリのおかげで、コード生成向けの言語としては非常に優れている
    • LLMの利用は結局、画一的で凡庸なコードを大量生産することになるだろう
    • LLMでコードを書くという発想そのものを捨てるべきだと思う
      Rob Pikeの警告どおり、こうした技術はソフトウェア生態系の汚染
      多くの人は「便利さ」というスロップ(slop) を求めているが、それこそが問題の本質だ
  • ソースコードを自動で最新スタイルへ変換してくれるツールは本当に素晴らしい
    JavaのOpenRewriteが代表例だが、他の言語では同様のものがあまり思い浮かばない
    Goのようにこうした機能が言語に組み込まれているなら、言語の成熟度は大きく高まる
    今後の新しい言語は、Goのこうした統合的アプローチを参考にしそうだ

    • C言語にはCoccinelleがあり、2009年のLWN記事でも紹介されている
      JetBrainsのIDEは数百万行のコードを一度にリファクタリングしたり、新しい構文へ自動変換したりできる
      ConvertToPrimaryConstructor のような機能もある
      また、Structural Search and Replace は単なるテキストではなく言語構文レベルで動作する
      .NETのRoslynアナライザーもIDEでコード修正提案を提供する
      チュートリアルリンク
    • Rustのclippyは最新構文を推奨し、一部は自動修正も可能だ
      おかげでコードがずっときれいになった
    • Haskellのhlintもかなり前から存在していた
      concatmapconcatMapに変えたり、不要なif式を簡略化してくれる
    • TypeScriptコードベースをこういう形で変換したことがある人がいるのか気になる
      LSPサーバーは機能不足で、引数削除のような基本的なリファクタリングすらサポートしていない
      jscodeshiftClaudeを組み合わせれば可能なのか考えている
  • こうした自動修正ツール(go fix) のおかげで、Goは本当に優れた言語だ
    新機能のrangeintもgo fixで自動反映される予定なので期待している
    Goチームに賛辞を送りたい

    • 他の言語を使いたいと思うことも多いが、Goのビルド・テスト・lintツールがあまりに優秀なので結局Goを使ってしまう
      コンパイル速度も信じられないほど速い
    • 以前は自分で正規表現を使ってforループを探して修正していたが、今ではこのツールがずっと洗練された方法で処理してくれる
  • 記事では触れられていないが、私が一番気に入っている機能は//go:fix inlineディレクティブだ
    1行関数を呼び出し元へインライン展開してくれる
    ライブラリ作者が旧バージョンの関数を新バージョンへ自然に自動移行できるようにしてくれる
    semverが変わってもgo fixで自動アップグレードが可能だ

  • 最近見たWes McKinneyのポッドキャストで、
    Goは高速なコンパイル・実行サイクル強い型システムマルチスレッド安全性のおかげでコーディングエージェントに理想的だと言っていた
    その話を聞いてGoにまた興味が湧いてきた

  • Goの確立されたツール体系と慣習はエージェントベース開発に大いに役立つ
    go run main.goですぐに開発環境を立ち上げられ、複数のワークツリーや中央設定、マイグレーション済みDBまでサポートできる
    housecat-inc/cheetahでこうしたツールを共有している
    go generate, go build, go test, go vetまで含んだ高速ループにgo fixを追加するつもりだ

    • 超高速なコンパイル速度はLLMの反復実験にも大きな利点になる
  • Pythonを学んでいると、同じことをする方法が多すぎて一貫性がない
    Cのように1つのやり方しかないほうがむしろ恋しくなる
    Goはこの段階に達しているのだろうか
    LLMの助けがなくてもベストプラクティスに従える言語なのか知りたい

    • Goはかなり意見のはっきりした言語なので、たいていは1つのやり方しかない
      複雑さを避けて単純さを保とうとする努力が印象的だ
      Pythonの混乱に疲れた人には勧められる
  • セルフサービスアナライザーという概念が本当に興味深い
    大規模ライブラリやインフラチームで積極的に活用されそうだ

  • こういうツールがあるなら、後方互換性のない言語も可能なのではないかという気がしてくる

  • TypeScriptの世界ではbiomeがこうした役割を果たしている
    たとえばforEachの代わりにfor...ofを推奨し、ultraciteと一緒に使うとワークフローがずっと滑らかになる
    agents.mdファイルに「修正後にbiome fixを実行」と明記してあり、そのおかげでコード品質が自動的に保たれている
    eslintよりずっと軽量で効率的な体験