go fmtとgofmtの違いと使い分け

goのフォーマッタとしてgofmt と go fmtがあることを知った。

go fmt

go fmtはgoのサブコマンドとして実装されているフォーマッタ。 その実態は gofmt -l -w を指定パスに対して適用してくれる。

$ go help fmt 
usage: go fmt [-n] [-x] [packages]

Fmt runs the command 'gofmt -l -w' on the packages named
by the import paths. It prints the names of the files that are modified.

gofmt

pkg.go.dev

フォーマッタの実態。 差分表示(-d)やコード簡略化(-s)など、go fmtでは指定されていない細かなオプションなどを指定できる。

$ gofmt -h
usage: gofmt [flags] [path ...]
  -cpuprofile string
        write cpu profile to this file
  -d    display diffs instead of rewriting files
  -e    report all errors (not just the first 10 on different lines)
  -l    list files whose formatting differs from gofmt's
  -r string
        rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
  -s    simplify code
  -w    write result to (source) file instead of stdout

何が違うのか、どう使い分けるのか

go fmt 実行時に指定されるオプションの -l-w なので、デフォルトルールでフォーマットの修正を適用した上で修正したファイル一覧を出力してくれる。 なので基本的な動作は同じ。

基本的にはフォーマッタを適用して欲しいので、普段使いとしては go fmt ./... でよさそう。 CIで差分検知だけして書き換えまでは行いたくないときや、書き換えルールをカスタマイズしたいような特別なケースで gofmt を使えばよさそう。