Goブログ

go fmt でコードを整形する

Andrew Gerrand
2013年1月23日

はじめに

Gofmt は、Goのソースコードを自動的に整形するツールです。

Gofmt で整形されたコードは

  • 書きやすくなる: ハックしている間、細かいフォーマットの問題を気にする必要がありません。

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

  • 保守しやすくなる: ソースへの機械的な変更によって、ファイルのフォーマットに関係のない変更が生じることがありません。diffには実際の変更のみが表示されます。

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

コードを整形する

最近、世の中の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ユーザー向けに、GoClipseおよびGoSublimeプロジェクトは、それらのエディターにgofmt機能を追加します。

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

機械的なソース変換

機械的にフォーマットされたコードの最大の利点の1つは、diffに関係のないフォーマットノイズを生成することなく、機械的に変換できることです。機械的な変換は、大規模なコードベースを扱う場合に非常に貴重です。手動で大規模な変更を行うよりも、より包括的でエラーが発生しにくいためです。実際、大規模(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の前は、組み込みのエラーインターフェースが存在せず、慣例としてos.Error型を使用していました。エラーを導入したときに、os.Errorとその関連ヘルパー関数へのすべての参照をerrorと新しいerrorsパッケージを使用するように書き換えるgofixモジュールを提供しました。手動で試みるのは困難だったでしょうが、コードが標準形式であるため、存在していたほぼすべてのGoコードに触れたこの変更を準備、実行、およびレビューすることは比較的簡単でした。

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

次の記事: Goマップの活用
前の記事: 並行処理は並列処理ではない
ブログインデックス