aboutsummaryrefslogtreecommitdiff
path: root/content/gofmt.article
diff options
context:
space:
mode:
Diffstat (limited to 'content/gofmt.article')
-rw-r--r--content/gofmt.article103
1 files changed, 103 insertions, 0 deletions
diff --git a/content/gofmt.article b/content/gofmt.article
new file mode 100644
index 0000000..7aa3428
--- /dev/null
+++ b/content/gofmt.article
@@ -0,0 +1,103 @@
+# 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-Run_gofmt_on_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).