メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

新機能

go fixにatomictypes・embedlit・slicesbackward・unsafefuncsの4つの新modernizerが追加された

go fix

この項目の注釈は AI により生成されており、誤りを含む場合があります。
使用例のコンパイル検証: 未検証(コンパイル確認未了)

概要

go fix コマンドに新しいmodernizer(コードの自動近代化リライトを行うアナライザ)が4つ追加された。

  • atomictypes: sync/atomic の基本型向け関数呼び出しを、atomic.Int32 のような専用の atomic 型に置き換える。
  • embedlit: 複合リテラル中の埋め込みフィールドへの冗長な型指定を取り除く。
  • slicesbackward: スライスを逆順に走査する手書きループを slices.Backward を使った書き方に置き換える。
  • unsafefuncs: unsafe.Pointer に対するポインタ演算を unsafe.Add などのヘルパー関数呼び出しに置き換える。

いずれも golang.org/x/tools/go/analysis/passes/modernize パッケージのアナライザとして実装されており、go fix はデフォルトでこれらすべてを実行する。

使用例

Before

package main

import "sync/atomic"

var counter int32

func incr() {
	atomic.AddInt32(&counter, 1)
}

After

package main

import "sync/atomic"

var counter atomic.Int32

func incr() {
	counter.Add(1)
}

移行時の注意

atomictypes の書き換えは、対象変数へのすべてのアクセスが atomic.AddInt32(&v, ...) のような形の呼び出しの中に限定されている場合にのみ提案される。非同期的な読み出し(if v == 0 など)が混在している変数は書き換え対象外となるため、go fix が変換候補として提示しなかった変数についてはデータ競合の見落としがないか別途確認するとよい。

実装解説

4つのmodernizerはいずれも cmd/vendor/golang.org/x/tools/go/analysis/passes/modernize パッケージに実装され、modernize.Suite 経由で go fix (cmd/fix) の デフォルトSuite に組み込まれている。

  • atomictypes: runAtomicsync/atomic の関数呼び出し atomic.AddInt32(&v, ...) 等から候補変数 v を集め、その変数へのすべての参照がatomic呼び出しの中でのみ現れる場合に限り atomic.Int32 等への書き換えを提案する。
  • embedlit: runEmbedLit が2種類のパターンを扱う。embedlitUnnestT{U: U{f: v}} のような冗長な埋め込み型指定を除去し、embedlitCombine は埋め込みフィールドへの代入文をリテラル初期化の中に統合する。
  • slicesbackward: slicesbackwardfor i := len(s) - 1; i >= 0; i-- 形式のループを検出し、slices.Backward を使った range ループに書き換える。
  • unsafefuncs: unsafefuncsunsafe.Pointer(uintptr(ptr) + uintptr(n)) の形のポインタ演算式を検出し、deleteConv で不要な変換を取り除きつつ unsafe.Add(ptr, n) へ書き換える。

関連リンク