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 用户,Vim for Go 插件 包含一个 :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 钩子。

机械源代码转换

机器格式化代码最大的优点之一是它可以进行机械转换,而不会在 diff 中产生不相关的格式噪音。当处理大型代码库时,机械转换是无价的,因为它比手动进行大范围的更改更全面、更不容易出错。事实上,在规模化工作(如我们在 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 Map 的使用
上一篇文章:并发不是并行
博客索引