| # go fmt your code |
| 23 Jan 2013 |
| Tags: gofix, gofmt, technical |
| Summary: How and why to format your Go code using gofmt. |
| OldURL: /go-fmt-your-code |
| |
| Andrew Gerrand |
| |
| ## Introduction |
| |
| [Gofmt](https://golang.org/cmd/gofmt/) is a tool that automatically formats Go source code. |
| |
| Gofmt'd code is: |
| |
| - easier to **write**: never worry about minor formatting concerns while hacking away, |
| |
| - easier to **read**: when all code looks the same you need not mentally convert |
| others' formatting style into something you can understand. |
| |
| - easier to **maintain**: mechanical changes to the source don't cause unrelated |
| changes to the file's formatting; |
| diffs show only the real changes. |
| |
| - **uncontroversial**: never have a debate about spacing or brace position ever again! |
| |
| ## Format your code |
| |
| We recently conducted a survey of Go packages in the wild and found that |
| about 70% of them are formatted according to gofmt's rules. |
| This was more than expected - and thanks to everyone who uses gofmt - but |
| it would be great to close the gap. |
| |
| To format your code, you can use the gofmt tool directly: |
| |
| gofmt -w yourcode.go |
| |
| Or you can use the "[go fmt](https://golang.org/cmd/go/#hdr-Gofmt__reformat__package_sources)" command: |
| |
| go fmt path/to/your/package |
| |
| To help keep your code in the canonical style, |
| the Go repository contains hooks for editors and version control systems |
| that make it easy to run gofmt on your code. |
| |
| For Vim users, the [Vim plugin for Go](https://github.com/fatih/vim-go) |
| includes the :Fmt command that runs gofmt on the current buffer. |
| |
| For emacs users, [go-mode.el](https://github.com/dominikh/go-mode.el) |
| provides a gofmt-before-save hook that can be installed by adding this line |
| to your .emacs file: |
| |
| (add-hook 'before-save-hook #'gofmt-before-save) |
| |
| For Eclipse or Sublime Text users, the [GoClipse](https://github.com/GoClipse/goclipse) |
| and [GoSublime](https://github.com/DisposaBoy/GoSublime) projects add |
| a gofmt facility to those editors. |
| |
| And for Git aficionados, the [misc/git/pre-commit script](https://github.com/golang/go/blob/release-branch.go1.1/misc/git/pre-commit) |
| is a pre-commit hook that prevents incorrectly-formatted Go code from being committed. |
| If you use Mercurial, the [hgstyle plugin](https://bitbucket.org/fhs/hgstyle/overview) |
| provides a gofmt pre-commit hook. |
| |
| ## Mechanical source transformation |
| |
| One of the greatest virtues of machine-formatted code is that it can be |
| transformed mechanically without generating unrelated formatting noise in the diffs. |
| Mechanical transformation is invaluable when working with large code bases, |
| as it is both more comprehensive and less error prone than making wide-sweeping changes by hand. |
| Indeed, when working at scale (like we do at Google) it often isn't practical |
| to make these kinds of changes manually. |
| |
| The easiest way to mechanically manipulate Go code is with gofmt's -r flag. |
| The flag specifies a rewrite rule of the form |
| |
| pattern -> replacement |
| |
| where both pattern and replacement are valid Go expressions. |
| In the pattern, single-character lowercase identifiers serve as wildcards |
| matching arbitrary sub-expressions, |
| and those expressions are substituted for the same identifiers in the replacement. |
| |
| For example, this[ recent change](https://golang.org/cl/7038051) to the |
| Go core rewrote some uses of [bytes.Compare](https://golang.org/pkg/bytes/#Compare) |
| to use the more efficient [bytes.Equal](https://golang.org/pkg/bytes/#Equal). |
| The contributor made the change using just two gofmt invocations: |
| |
| gofmt -r 'bytes.Compare(a, b) == 0 -> bytes.Equal(a, b)' |
| gofmt -r 'bytes.Compare(a, b) != 0 -> !bytes.Equal(a, b)' |
| |
| Gofmt also enables [gofix](https://golang.org/cmd/fix/), |
| which can make arbitrarily complex source transformations. |
| Gofix was an invaluable tool during the early days when we regularly made |
| breaking changes to the language and libraries. |
| For example, before Go 1 the built-in error interface didn't exist and the |
| convention was to use the os.Error type. |
| When we [introduced error](https://golang.org/doc/go1.html#errors), |
| we provided a gofix module that rewrote all references to os.Error and its |
| associated helper functions to use error and the new [errors package](https://golang.org/pkg/errors/). |
| It would have been daunting to attempt by hand, |
| but with the code in a standard format it was relatively easy to prepare, |
| execute, and review this change which touched almost all Go code in existence. |
| |
| For more about gofix, see [this article](https://blog.golang.org/introducing-gofix). |