Go 部落格

go fmt 你的程式碼

Andrew Gerrand
2013 年 1 月 23 日

引言

Gofmt 是一個自動格式化 Go 原始碼的工具。

經 Gofmt 格式化後的程式碼

  • 更易於 編寫:編碼時無需擔心細微的格式問題,

  • 更易於 閱讀:當所有程式碼看起來都一樣時,你無需在腦海中將他人的格式風格轉換成你能理解的樣子。

  • 更易於 維護:對原始碼進行機械化修改不會導致檔案格式發生不相關的變化;差異(diffs)僅顯示實際的修改。

  • 無爭議:再也不用為縮排或大括號的位置爭論不休了!

格式化你的程式碼

我們最近對社群中的 Go 包進行了一項調查,發現其中約 70% 的包是按照 gofmt 的規則進行格式化的。這比預期的要多——感謝所有使用 gofmt 的人——但如果能縮小這個差距就太好了。

要格式化你的程式碼,你可以直接使用 gofmt 工具

gofmt -w yourcode.go

或者你可以使用 “go fmt” 命令

go fmt path/to/your/package

為了幫助你的程式碼保持規範風格,Go 倉庫包含了適用於編輯器和版本控制系統的鉤子(hooks),可以輕鬆地在你的程式碼上執行 gofmt。

對於 Vim 使用者,Go 的 Vim 外掛 包含 :Fmt 命令,可以在當前緩衝區上執行 gofmt。

對於 emacs 使用者,go-mode.el 提供了一個 gofmt-before-save 鉤子,可以透過在你的 .emacs 檔案中新增以下行來安裝

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

對於 Eclipse 或 Sublime Text 使用者,GoClipseGoSublime 專案為這些編輯器添加了 gofmt 功能。

對於 Git 愛好者,misc/git/pre-commit 指令碼 是一個 pre-commit 鉤子,可以防止提交格式不正確的 Go 程式碼。如果你使用 Mercurial,hgstyle 外掛 提供了一個 gofmt pre-commit 鉤子。

機械化原始碼轉換

機器格式化程式碼的最大優點之一是它可以進行機械化轉換,而不會在差異(diffs)中產生不相關的格式噪音。在處理大型程式碼庫時,機械化轉換非常寶貴,因為它比手動進行大範圍修改更全面且不易出錯。實際上,在規模化工作時(就像我們在 Google 所做的那樣),手動進行這些型別的更改通常是不切實際的。

機械化操作 Go 程式碼最簡單的方法是使用 gofmt 的 -r 標誌。該標誌指定了以下形式的重寫規則

pattern -> replacement

其中 pattern 和 replacement 都是有效的 Go 表示式。在 pattern 中,單字元小寫識別符號用作萬用字元,匹配任意子表示式,並且這些子表示式在 replacement 中替換相同的識別符號。

例如,Go 核心的這最近更改bytes.Compare 的一些用法重寫為使用更高效的 bytes.Equal。貢獻者僅用了兩次 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 時,我們提供了一個 gofix 模組,它將所有對 os.Error 及其相關輔助函式的引用重寫為使用 error 和新的 errors 包。手動嘗試會令人望而卻步,但有了標準格式的程式碼,準備、執行和審查這項幾乎涉及所有現有 Go 程式碼的更改相對容易。

有關 gofix 的更多資訊,請參閱這篇文章

下一篇文章:Go maps 實戰
上一篇文章:併發不是並行
部落格索引