The Go Blog

コードをgo fmtする

Andrew Gerrand
2013年1月23日

はじめに

Gofmtは、Goのソースコードを自動的にフォーマットするツールです。

Gofmtでフォーマットされたコードは、

  • 書きやすい: ハッキング中に細かいフォーマットの心配をする必要がありません。

  • 読みやすい: すべてのコードが同じように見えるため、他の人のフォーマットスタイルを理解できるものに頭の中で変換する必要がありません。

  • 保守しやすい: ソースへの機械的な変更は、ファイルのフォーマットに無関係な変更を引き起こしません。差分は実際の変更のみを表示します。

  • 異論の余地がない: スペースやブレースの位置について二度と議論する必要はありません!

コードをフォーマットする

最近、実際に使われているGoパッケージの調査を実施したところ、約70%がgofmtのルールに従ってフォーマットされていることがわかりました。これは予想以上であり、gofmtを使用している皆様に感謝しますが、このギャップを埋めることができれば素晴らしいでしょう。

コードをフォーマットするには、gofmtツールを直接使用できます

gofmt -w yourcode.go

または、「go fmt」コマンドを使用できます

go fmt path/to/your/package

コードを標準的なスタイルに保つために、Goリポジトリには、エディターやバージョン管理システム用のフックが含まれており、コードに対してgofmtを簡単に実行できます。

Vimユーザーの場合、Go用Vimプラグインには、現在のバッファでgofmtを実行する:Fmtコマンドが含まれています。

Emacsユーザーの場合、go-mode.elは、.emacsファイルにこの行を追加することでインストールできるgofmt-before-saveフックを提供します

(add-hook 'before-save-hook #'gofmt-before-save)

EclipseまたはSublime Textユーザーの場合、GoClipseGoSublimeプロジェクトは、これらのエディターにgofmt機能を追加します。

そして、Git愛好家のために、misc/git/pre-commitスクリプトは、誤ってフォーマットされたGoコードがコミットされるのを防ぐプリコミットフックです。Mercurialを使用している場合、hgstyleプラグインはgofmtプリコミットフックを提供します。

機械的なソース変換

機械的にフォーマットされたコードの最大の利点の1つは、差分に無関係なフォーマットノイズを生成することなく、機械的に変換できることです。大規模なコードベースで作業する場合、手作業で広範囲にわたる変更を行うよりも、包括的でエラーが少ないため、機械的な変換は非常に貴重です。実際、大規模(Googleで行っているように)で作業する場合、これらの種類の変更を手動で行うことは現実的ではないことがよくあります。

Goコードを機械的に操作する最も簡単な方法は、gofmtの-rフラグを使用することです。このフラグは、次の形式の書き換えルールを指定します。

pattern -> replacement

ここで、patternとreplacementの両方が有効なGoの式です。パターンでは、1文字の小文字の識別子が任意のサブ式と一致するワイルドカードとして機能し、これらの式はreplacement内の同じ識別子に置き換えられます。

たとえば、Goコアに対するこの最近の変更では、bytes.Compareの一部を、より効率的なbytes.Equalを使用するように書き換えました。貢献者は、わずか2つのgofmt呼び出しで変更を行いました。

gofmt -r 'bytes.Compare(a, b) == 0 -> bytes.Equal(a, b)'
gofmt -r 'bytes.Compare(a, b) != 0 -> !bytes.Equal(a, b)'

Gofmtは、任意の複雑なソース変換を行うことができるgofixも有効にします。Gofixは、言語やライブラリに破壊的な変更を定期的に加えていた初期の頃には非常に貴重なツールでした。たとえば、Go 1以前は、組み込みのerrorインターフェースは存在せず、慣習的にos.Error型を使用していました。私たちがerrorを導入したとき、os.Errorとその関連ヘルパー関数へのすべての参照を、errorと新しいerrorsパッケージを使用するように書き換えるgofixモジュールを提供しました。手作業で試みるのは困難だったでしょうが、コードが標準形式であるため、既存のほぼすべてのGoコードに影響を与えるこの変更を準備、実行、レビューすることは比較的簡単でした。

gofixの詳細については、この記事を参照してください。

次の記事: Goのマップの実際
前の記事: 並行性は並列性ではない
ブログインデックス