<h2 id="introduction">Introduction</h2>
<p>
-Go is a new programming language.
-It eliminates some of the pitfalls in languages
-like C++ and Java but introduces other ones.
-Many remain the same.
-This page gives tips for writing clear, idiomatic Go code
+This document gives tips for writing clear, idiomatic Go code
and points out common mistakes to avoid.
It augments the <a href="go_spec.html">language specification</a>
and the <a href="go_tutorial.html">tutorial</a>, both of which you
-should be familiar with.
+should read first.
</p>
-<h3 id="read">Read</h3>
+<h3 id="read">Read good code</h3>
<p>
-The first step to improving as a writer is to read.
-This step is as necessary for programming as it is for prose,
-and it is skipped as often by programmers as by writers.
+The first step towards learning to write good code is to read good code.
The <a href="/src/pkg/">Go package sources</a>
are intended to serve not
only as the core library but also as examples of how to
-use the language. Read them.
+use the language. Read them and follow their example.
</p>
<h3 id="be-consistent">Be consistent</h3>
<p>
Consistency makes programs easy to read.
If a program says the same thing twice,
-it should say it the same way both times,
-so that the parallel structure is clear.
-Conversely, if two different sections of
+it should say it the same way both times.
+Conversely, if two different sections of a
program look different, the reader will
-expect them to be doing different things.
+expect them to do different things.
</p>
<p>
<p>
The convention in most languages (including Go)
-is to count up unless doing so would be incorrect.
-A loop that counts down implicitly says “there's
-a specific reason to count down here; this situation is special.”
-A reader who finds a program in which half the
-loops count up and the other half count down
+is to count up unless to do so would be incorrect.
+A loop that counts down implicitly says “something
+special is happening here.”
+A reader who finds a program in which some
+loops count up and the rest count down
will spend time trying to understand why.
-A programmer who inserts counting-down
-loops for variety wastes the reader's time.
+Don't run loops backwards unless it's necessary.
</p>
<p>
-Loop direction is hardly the only
+Loop direction is just one
programming decision which a programmer
-might want to use to be distinctive:
+may be tempted to be distinctive:
tabs or spaces, choice of variable names,
choice of method names, whether a type
has a constructor, what tests look like, and on and on.
As in the loop example, inconsistency
sows confusion, and wastes time.
-Why is this variable called n here and cnt here?
+Why is this variable called <code>n</code> here and <code>cnt</code> there?
Why is the <code>Log</code> constructor <code>CreateLog</code> when
-the <code>Vector</code> constructor is <code>NewVector</code>?
+the <code>List</code> constructor is <code>NewList</code>?
Why is this data structure initialized using
-a structure literal when this other one
+a structure literal when that one
is initialized using individual assignments?
-Why is this idiom used here but not there?
-And on and on.
+And so on.
These questions distract from the important one:
what does the code do?
+Moreover, internal consistency is important not only within a single file,
+but also within the the surrounding source files.
Being consistent about little things
lets readers concentrate on big ones.
</p>
<p>
-This document describes how to use Go effectively.
-Equally important, it describes how to use Go idiomatically,
-so that a Go programmer seeing your code for
+This document describes how to use Go effectively and idiomatically
+so that a programmer seeing your code for
the first time can focus on what it does
and not why it is inconsistent with typical Go practices.
Consistency trumps every item listed below.
and try to mimic it as much as possible, even if it
disagrees with the rules here.
It should not be possible to tell which lines
-you wrote or edited.
-</p>
-
-<p>
-Internal consistency is important in a single file,
-but source files do not exist in isolation.
-Code must be consistent with the surrounding source file as well,
-or the same problems arise.
+you wrote or edited based on style alone.
</p>
<h2 id="formatting">Formatting</h2>
<p>
Formatting issues are the most contentious
but the least consequential.
-People adapt quite well to different formatting styles,
-even if at first the styles “look weird.”
-The most important consideration is that if everyone
-uses the same formatting, then a reader picking up an
-unfamiliar piece of code can focus on what
-the code does instead of what it looks like.
-Most of the local formatting style can and should be
-picked up by reading existing Go programs (see above).
-The following are the most common issues
-that Google programmers run into.
+People adapt to different formatting styles,
+even if at first the styles “look weird,”
+but they shouldn't be asked to.
+Everyone
+should use the same formatting; as in English,
+consistent punctuation and spacing make the
+text easier to read.
+Most of the local formatting style can be
+picked up by reading existing Go programs (see above),
+but to make them explicit here are some common points.
</p>
<h3 id="tabs">Use tabs</h3>
<h3 id="white-space">Trim trailing white space</h3>
<p>
-Files should not contain trailing white space at the end of lines.
-The script <code>/home/rsc/bin/g4ws</code> removes trailing
-whitespace from all open files in the current g4 client.
+There should be no trailing white space at the end of lines.
</p>
<h3 id="line-wrapping">Don't wrap lines mechanically</h3>
<p>
Go has no 80-character limit. Don't bother with fancy line
wrapping just because a line is wider than a punched card.
-If you must wrap a line, indent with a single tab.
+If you must wrap a line, indent with an extra tab.
</p>
-<h3 id="parens">Omit parentheses</h3>
+<h3 id="parens">Omit parentheses in control structures</h3>
<p>Go does not require parentheses around the expression
following the <code>for</code>, <code>if</code>, <code>range</code>,
-and <code>switch</code> keywords.
+<code>switch</code>, and <code>return</code> keywords.
</p>
<h3 id="line-comments">Use line comments</h3>
<p>
Go provides C-style <code>/* */</code> block comments
and C++-style <code>//</code> line comments.
-The local style is to use line comments by default,
+Use line comments by default,
reserving block comments for top-level package comments
and commenting out large swaths of code.
</p>
<p>
If a comment immediately precedes a top-level declaration,
the <a href="/">Go documentation server</a>
+<font color=red>(TODO: that's not a public URL.)</font>
uses that comment as the documentation
-for the constant, function, package, type or variable being declared.
+for the constant, function, method, package, type or variable being declared.
+These are called <i>doc comments</i>.
To detach a comment from a declaration, insert a blank
line between them.
</p>
<p>
Every exported (capitalized) name in a program should
have a doc comment, as should the package declaration itself.
+If a name appears multiple times due to forward declarations
+or appearance in multiple source files within a package, only
+one instance requires a doc comment, and any one will do.
</p>
<p>
func Quote(s string) string {
</pre>
-<p>
-instead of:
-</p>
-
-<pre class="bad">
-/* not Go style */
-// Return a double-quoted Go string literal representing s....
-func Quote(s string) string {
-</pre>
-
<p>
The complete English sentence form admits
a wider variety of automated presentations.
In particular, don't assume that a single space is the same
width as every other character.
If you need to make a columnated table, use tabs to separate
-the columns and the pretty printer (in progress) will make
+the columns and the pretty printer will make
sure the columns are lined up properly in the output.
</p>
*/
</pre>
-<p>
-instead of:
-</p>
+or
-<pre class="bad">
-/* not Go style */
-//////////////////////////////////////////////////////////////////////
-// Helper routines for simplifying the fetching of optional fields of basic type.
-// If the field is missing, they return the zero for the type.
+<pre>
+/*
+ Helper routines for simplifying the fetching of optional fields of basic type.
+ If the field is missing, they return the zero for the type.
+ */
</pre>
<p>
-Comments are text, not HTML, and not any kind of markup.
+Comments are text, not HTML; they contain no markup.
Refrain from ASCII embellishment like *this* or /this/.
-As usual, read the Go sources for examples.
</p>
<h2 id="names">Names</h2>
<p>
Go uses the case of the first letter in a name to decide
whether the name is visible in other packages.
-In Go, multiword names use MixedCaps or mixedCaps
+Multiword names use MixedCaps or mixedCaps
rather than underscores.
</p>
<h3 id="package-names">Use short package names</h3>
<p>
-Package names are lowercase single-word names:
+Package names are lower case single-word names:
there should be no need for underscore or mixedCaps.
The package name is conventionally the base name of
the source directory: the package in <code>src/pkg/container/vector</code>
-is installed as <code>"container/vector"</code> but has name vector,
+is installed as <code>"container/vector"</code> but has name <code>vector</code>,
not <code>container_vector</code> and not <code>containerVector</code>.
The package name is only the default name used
-when importing the package; it need not be a unique
-identifier.
+when importing the package; it need not be unique
+across all source code.
</p>
-<h3 id="name-length">Avoid lengthy names</h3>
+<h3 id="name-length">Avoid long names</h3>
<p>
A name's length should not exceed its information content.
For a function-local variable
in scope only for a few lines, the name <code>i</code> conveys just
as much information as <code>index</code> or <code>idx</code> and is easier to read.
-On the same note, <code>i</code> and <code>j</code> are better pair of names for
-index variables than <code>i1</code> and <code>i2</code> (or, worse, <code>index1</code> and <code>index2</code>),
-because they are easier to tell apart when reading
-the program quickly.
+Letters are easier to distinguish than numbers; use <code>i</code> and <code>j</code>
+not <code>i1</code> and <code>i2</code>.
</p>
<p>
-Exported names must convey more information,
-because they appear in a larger variety of contexts.
+Exported names must convey more information
+because they appear far from their origin.
Even so, longer names are not always better,
and the package name can help convey information:
the buffered <code>Reader</code> is <code>bufio.Reader</code>, not <code>bufio.BufReader</code>.
<p>
One-method interfaces are conventionally named by
the method name plus the -er suffix: <code>Reader</code>,
-<code>Writer</code>, <code>Formatter</code>. Using an interface name distinct
-from the method name keeps an anonymous struct
-field of type <code>Reader</code> from conflicting with its own
-<code>Read</code> method.
+<code>Writer</code>, <code>Formatter</code>.
</p>
<h3 id="common-names">Use canonical names</h3>
has the same signature and meaning.
Conversely, if your type implements a method with the
same meaning as a method on a well-known type,
-give it the same name and, equally important, the same signature.
+give it the same name and signature.
</p>
<p>
<p>
If an <code>if</code> body doesn't flow off the end of the
body—that is, the body ends in <code>break</code>, <code>continue</code>,
-<code>goto</code>, or <code>return</code>—it is preferable to omit the <code>else</code>.
-</p>
-
-<p>
-For example:
+<code>goto</code>, or <code>return</code>—omit the <code>else</code>.
</p>
<pre>
return err;
}
codeUsing(f);
-f.Close();
-moreCode();
</pre>
-<p>
-is preferable to:
-
-<pre class="bad">
-/* not Go style */
-if f, err := os.Open(name, os.O_RDONLY, 0); err != nil {
- return err;
-} else {
- codeUsing(f);
- f.Close();
-}
-moreCode();
-</pre>
-
-<p>
-The first form
-avoids unnecessary indentation
-and makes it clear that <code>moreCode()</code>
-only runs when <code>f.Close()</code> does.
-</p>
-
<h3 id="switch">Switch</h3>
<p>
-Go's <code>switch</code> is more powerful than C's.
+Go's <code>switch</code> is more general than C's.
When an <code>if</code>-<code>else if</code>-<code>else</code> chain has three or more bodies,
or an <code>if</code> condition has a long list of alternatives,
-consider rewriting it using <code>switch</code>.
+it will be clearer if rewritten as a <code>switch</code>.
</p>
-<a href="/src/pkg/bytes/bytes.go">go/src/pkg/bytes/bytes.go</a>:
-<pre>
-// Compare returns an integer comparing the two byte arrays lexicographically.
-// The result will be 0 if a==b, -1 if a < b, and +1 if a > b
-func Compare(a, b []byte) int {
- for i := 0; i < len(a) && i < len(b); i++ {
- switch {
- case a[i] > b[i]:
- return 1
- case a[i] < b[i]:
- return -1
- }
- }
- switch {
- case len(a) < len(b):
- return -1
- case len(a) > len(b):
- return 1
- }
- return 0
-}
-</pre>
-
<a href="/src/pkg/http/url.go">go/src/pkg/http/url.go</a>:
<pre>
func unhex(c byte) byte {
<pre>
func shouldEscape(c byte) bool {
switch c {
- case ' ', '?', '&', '=', '#', '+', '%':
+ case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
</pre>
+<a href="/src/pkg/bytes/bytes.go">go/src/pkg/bytes/bytes.go</a>:
+<pre>
+// Compare returns an integer comparing the two byte arrays lexicographically.
+// The result will be 0 if a==b, -1 if a < b, and +1 if a > b
+func Compare(a, b []byte) int {
+ for i := 0; i < len(a) && i < len(b); i++ {
+ switch {
+ case a[i] > b[i]:
+ return 1
+ case a[i] < b[i]:
+ return -1
+ }
+ }
+ switch {
+ case len(a) < len(b):
+ return -1
+ case len(a) > len(b):
+ return 1
+ }
+ return 0
+}
+</pre>
+
<h2 id="functions">Functions</h2>
<h3 id="omit-wrappers">Omit needless wrappers</h3>
<p>
-Functions are great for factoring out common functionality.
-If a function is only called once,
-ask whether the function is really necessary,
+Functions are great for factoring out common code, but
+if a function is only called once,
+ask whether it is necessary,
especially if it is just a short wrapper around another function.
-This style runs rampant in C++ code: wrappers
+This style is rampant in C++ code: wrappers
call wrappers that call wrappers that call wrappers.
-Doing this hinders people trying to understand the program,
+This style hinders people trying to understand the program,
not to mention computers trying to execute it.
</p>
<p>
If a function must return multiple values, it can
do so directly.
-The C “pass in a pointer to a return value”
-idiom is dead.
+There is no need to pass a pointer to a return value.
</p>
-
<h2 id="errors">Errors</h2>
<h3 id="handle-errors-first">Handle errors first</h3>
<p>
-Errors tend to be simpler than non-error cases,
+Error cases tend to be simpler than non-error cases,
and it helps readability when the non-error flow
of control is always down the page.
Also, error cases tend to end in jumps,
</p>
<pre>
+if len(name) == 0 {
+ return;
+}
+if IsDir(name) {
+ return;
+}
f, err := os.Open(name, os.O_RDONLY, 0);
if err != nil {
- return err;
+ return;
}
codeUsing(f);
-f.Close();
-moreCode();
-</pre>
-
-is preferable to:
-
-<pre class="bad">
-/* not Go style */
-f, err := os.Open(name, os.O_RDONLY, 0);
-if err == nil {
- codeUsing(f);
- f.Close();
-} else {
- return err;
-}
-moreCode();
</pre>
<h3 id="error-returns">Return <code>os.Error</code>, not <code>bool</code></h3>
<p>Packages that export only a single type sometimes
shorten <code>NewTypeName</code> to <code>New</code>;
-for example, the vector constructor is
+the vector constructor is
<code>vector.New</code>, not <code>vector.NewVector</code>.
</p>
return type <code>hash.Hash32</code>.
Substituting the CRC-32 algorithm for Adler-32 in a Go program
requires only changing the constructor call:
-the rest of the code cannot distinguish the two algorithms.
+the rest of the code is unaffected by the change of algorithm.
</p>
-<h3 id="">Use interface adapters to expand an implementation</h3>
+<h3 id="asdf">Use interface adapters to expand an implementation</h3>
XXX
-<h3 id="">Use anonymous fields to incorporate an implementation</h3>
+<h3 id="fdsa">Use anonymous fields to incorporate an implementation</h3>
XXX