こんにちは。Tomoyuki(@tomoyuki65)です。
Go言語(Golang)には破壊的変更を含む仕様変更が入った際に、自動修正するためのツールとして「go fix」コマンドがありましたが、Go言語は基本的に後方互換性を維持するため、このコマンドを利用する機会はほぼありませんでした。
そんなほぼ利用されない「go fix」コマンドですが、Goのバージョン1.26で刷新され、Goのコードを現代的な書き方へ自動修正するためのツールに変更されました。
この記事では、そんな刷新された「go fix」コマンドの使い方についてご紹介します。
Go言語(Golang)1.26で刷新された「go fix」の使い方|差分確認・自動修正によるコード移行
例えば以下のようなinterface{}型を使ったスクリプトがあったとします。
package main
import (
"fmt"
)
func printValue(v interface{}) {
fmt.Println(v)
}
func main() {
printValue("Hello World !!")
}
次に以下のコマンドを実行し、現代的な書き方へ修正できるかチェックします。
go fix -diff ./...
※必要に応じて適切なパスを指定してチェックして下さい。
実行後、修正箇所があれば以下のように表示されます。

※Go1.18からinterface{}のエイリアスとしてanyが追加されました。
次に以下のコマンドを実行し、コードを自動修正します。
go fix ./...
※必要に応じて適切なパスを指定して修正して下さい。
実行後、以下のようにコードが修正されればOKです。

このようにGoのバージョン1.26から「go fix」コマンドが刷新され、Goのコードを現代的な書き方へ自動修正することができるようになってます。
また、このような修正については、内部的に複数の「アナライザー(修正アルゴリズム)」を組み合わせて動作しており、特定のアナライザーを指定して修正することも可能です。
Goバージョン1.26時点のアナライザー一覧
| アナライザー | 説明 |
|---|---|
| any | interface{} を any に置き換える |
| buildtag | //go:build および // +build ディレクティブをチェックする |
| fmtappendf | []byte(fmt.Sprintf(...)) を fmt.Appendf(...) に置き換える |
| forvar | ループ変数の冗長な再宣言を削除する |
| hostport | net.Dial に渡されるアドレスの形式をチェックする |
| inline | go:fix inline コメントディレクティブに基づく修正を適用する |
| mapsloop | マップを走査する明示的なループを maps パッケージの呼び出しに置き換える |
| minmax | if/else 文を min または max の呼び出しに置き換える |
| newexpr | Go 1.26 の new(expr) を利用してコードを簡潔化する |
| omitzero | 構造体フィールドで omitempty を omitzero に置き換えることを提案する |
| plusbuild | 廃止された //+build コメントを削除する |
| rangeint | 3 要素形式の for ループを整数に対する for-range に置き換える |
| reflecttypefor | reflect.TypeOf(x) を TypeFor[T]() に置き換える |
| slicescontains | ループを slices.Contains または slices.ContainsFunc に置き換える |
| slicessort | 基本型に対する sort.Slice を slices.Sort に置き換える |
| stditerators | Len/At スタイル API の代わりにイテレーターを使用する |
| stringsbuilder | += による文字列連結を strings.Builder に置き換える |
| stringscut | strings.Index などを strings.Cut に置き換える |
| stringscutprefix | HasPrefix/TrimPrefix の組み合わせを CutPrefix に置き換える |
| stringsseq | Split/Fields の結果を range する処理を SplitSeq/FieldsSeq に置き換える |
| testingcontext | テスト内の context.WithCancel を t.Context に置き換える |
| waitgroup | wg.Add(1) / go / wg.Done() のパターンを wg.Go() に置き換える |
※利用可能なアナライザー一覧は「go tool fix help」で確認できます。例えばanyアナライザーのみチェックしたい場合は「go fix -diff -fix any ./…」、anyアナライザーのみ修正したい場合は「go fix -fix any ./…」を使うと可能です。
最後に
今回はGoのバージョン1.26で刷新された「go fix」コマンドの使い方についてご紹介しました。
新規機能開発時や、明示的にリファクタリングする際に利用することになると思うので、Goのバージョン1.26以上を利用する際はぜひ参考にしてみて下さい。


コメント