| |
| <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 |
| 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. |
| </p> |
| |
| <h3 id="read">Read</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 <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. |
| </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 |
| program look different, the reader will |
| expect them to be doing different things. |
| </p> |
| |
| <p> |
| Consider <code>for</code> loops. |
| Traditionally, a loop over <code>n</code> |
| elements begins: |
| </p> |
| |
| <pre> |
| for i := 0; i < n; i++ { |
| </pre> |
| |
| <p> |
| Much of the time, the loop could run in the opposite order |
| and still be correct: |
| </p> |
| |
| <pre> |
| for i := n-1; i >= 0; i-- { |
| </pre> |
| |
| <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 |
| will spend time trying to understand why. |
| A programmer who inserts counting-down |
| loops for variety wastes the reader's time. |
| </p> |
| |
| <p> |
| Loop direction is hardly the only |
| programming decision which a programmer |
| might want to use 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 the <code>Log</code> constructor <code>CreateLog</code> when |
| the <code>Vector</code> constructor is <code>NewVector</code>? |
| Why is this data structure initialized using |
| a structure literal when this other one |
| is initialized using individual assignments? |
| Why is this idiom used here but not there? |
| And on and on. |
| These questions distract from the important one: |
| what does the code do? |
| 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 |
| 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. |
| When editing code, read the surrounding context |
| 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. |
| </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. |
| </p> |
| |
| <h3 id="tabs">Use tabs</h3> |
| |
| <p> |
| The local style is to use tabs, not spaces, for indentation. |
| </p> |
| |
| <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. |
| </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. |
| </p> |
| |
| <h3 id="parens">Omit parentheses</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. |
| </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, |
| reserving block comments for top-level package comments |
| and commenting out large swaths of code. |
| </p> |
| |
| <h3 id="doc-comments">Write doc comments</h3> |
| |
| <p> |
| If a comment immediately precedes a top-level declaration, |
| the <a href="/">Go documentation server</a> |
| uses that comment as the documentation |
| for the constant, function, package, type or variable being declared. |
| 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. |
| </p> |
| |
| <p> |
| Doc comments consist of complete English sentences. |
| The first sentence should be a one-sentence summary that |
| starts with the name being declared: |
| </p> |
| |
| <pre> |
| // Quote returns a double-quoted Go string literal |
| // representing s. The returned string s uses Go escape |
| // sequences (\t, \n, \xFF, \u0100) for control characters |
| // and non-ASCII characters. |
| 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. |
| </p> |
| |
| |
| <h3 id="ascii-art">Avoid ASCII Art</h3> |
| |
| <p> |
| Go programs are meant to read equally well using |
| fixed-width and variable-width fonts. |
| Don't use fancy formattings that depend on fixed-width fonts. |
| 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 |
| sure the columns are lined up properly in the output. |
| </p> |
| |
| <p> |
| If you must use comments to separate |
| sections in a file, use a simple block comment: |
| </p> |
| |
| <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> |
| instead of: |
| </p> |
| |
| <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> |
| |
| <p> |
| Comments are text, not HTML, and not any kind of markup. |
| Refrain from ASCII embellishment like *this* or /this/. |
| As usual, read the Go sources for examples. |
| </p> |
| |
| <h2 id="names">Names</h2> |
| |
| <h3 id="mixed-caps">Use MixedCaps</h3> |
| |
| <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 |
| rather than underscores. |
| </p> |
| |
| <h3 id="package-names">Use short package names</h3> |
| |
| <p> |
| Package names are lowercase 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, |
| 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. |
| </p> |
| |
| <h3 id="name-length">Avoid lengthy 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. |
| </p> |
| |
| <p> |
| Exported names must convey more information, |
| because they appear in a larger variety of contexts. |
| 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>. |
| Similarly, <code>once.Do</code> is as precise and evocative as |
| <code>once.DoOrWaitUntilDone</code>, and <code>once.Do(f)</code> reads |
| better than <code>once.DoOrWaitUntilDone(f)</code>. |
| Contrary to popular belief, encoding small essays into |
| function names does not make it possible |
| to use them without documentation. |
| </p> |
| |
| <h3 id="interfacers">Use the -er convention for interface names</h3> |
| |
| <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. |
| </p> |
| |
| <h3 id="common-names">Use canonical names</h3> |
| |
| <p> |
| A few method names—<code>Read</code>, <code>Write</code>, <code>Close</code>, <code>Flush</code>, <code>String</code>—have |
| canonical signatures and meanings. To avoid confusion, |
| don't give your method one of those names unless it |
| 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. |
| </p> |
| |
| <p> |
| Some function-local variables have canonical names too. |
| Just as <code>i</code> is idiomatic in Go for an |
| index variable, <code>n</code> is idiomatic for a count, <code>b</code> for a <code>[]byte</code>, |
| <code>s</code> for a <code>string</code>, <code>r</code> for a <code>Reader</code>, |
| <code>err</code> for an <code>os.Error</code> |
| and so on. |
| Don't mix shorthands: it is especially confusing to |
| have two different variables <code>i</code> and <code>idx</code>, |
| or <code>n</code> and <code>cnt</code>. |
| </p> |
| |
| <h2 id="idioms">Idioms</h2> |
| |
| TODO: Add links to code once godoc can handle it. |
| |
| <h3 id="address-literals">Address literals to allocate and initialize</h3> |
| |
| <p> |
| Taking the address of a struct or array literal evaluates to a |
| new instance each time it is evaluated. |
| Use these expressions to avoid the repetition of filling |
| out a data structure. |
| </p> |
| |
| |
| <h3 id="buffer-slice">Use parallel assignment to slice a buffer</h3> |
| |
| <pre> |
| hdr, body, checksum := buf[0:20], buf[20:len(buf)], buf[len(buf)-4:len(buf)]; |
| </pre> |
| |
| <h2 id="control-flow">Control Flow</h2> |
| |
| <h3 id="else">Omit needless else bodies</h3> |
| |
| <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: |
| </p> |
| |
| <pre> |
| f, err := os.Open(name, os.O_RDONLY, 0); |
| if err != nil { |
| 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. |
| 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>. |
| </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 { |
| switch { |
| case '0' <= c && c <= '9': |
| return c - '0' |
| case 'a' <= c && c <= 'f': |
| return c - 'a' + 10 |
| case 'A' <= c && c <= 'F': |
| return c - 'A' + 10 |
| } |
| return 0 |
| } |
| </pre> |
| |
| <a href="/src/pkg/http/url.go">go/src/pkg/http/url.go</a>: |
| <pre> |
| func shouldEscape(c byte) bool { |
| switch c { |
| case ' ', '?', '&', '=', '#', '+', '%': |
| return true |
| } |
| return false |
| } |
| </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, |
| especially if it is just a short wrapper around another function. |
| This style runs rampant in C++ code: wrappers |
| call wrappers that call wrappers that call wrappers. |
| Doing this hinders people trying to understand the program, |
| not to mention computers trying to execute it. |
| </p> |
| |
| <h3 id="multiple-returns">Return multiple values</h3> |
| |
| <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. |
| </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, |
| and it helps readability when the non-error flow |
| of control is always down the page. |
| Also, error cases tend to end in jumps, |
| so that there is <a href="#else">no need for an explicit else</a>. |
| </p> |
| |
| <pre> |
| f, err := os.Open(name, os.O_RDONLY, 0); |
| if err != nil { |
| return err; |
| } |
| 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> |
| Few functions have just one failure mode. |
| Instead of returning a boolean to signal success, |
| return an <code>os.Error</code> that describes the failure. |
| Even if there is only one failure mode now, |
| there may be more later. |
| </p> |
| |
| <h3 id="error-context">Return structured errors</h3> |
| |
| Implementations of <code>os.Error</code>s should |
| describe the error but also include context. |
| For example, <code>os.Open</code> returns an <code>os.PathError</code>: |
| |
| <a href="/src/pkg/os/file.go">/src/pkg/os/file.go</a>: |
| <pre> |
| XXX definition of PathError and .String |
| </pre> |
| |
| <code>PathError</code>'s <code>String</code> formats |
| the error nicely and is the usual way the error gets used. |
| Callers that care about the precise error details can |
| use a type switch or a type guard to look for specific |
| errors and then extract details. |
| |
| <pre> |
| XXX example here - MkdirAll |
| </pre> |
| |
| <h2 id="types">Programmer-defined types</h2> |
| |
| <h3 id="constructors">Use <code>NewTypeName</code> for constructors</h3> |
| |
| <p> |
| The constructor for the type <code>pkg.MyType</code> should |
| be named <code>pkg.NewMyType</code> and should return <code>*pkg.MyType</code>. |
| The implementation of <code>NewTypeName</code> often uses the |
| <a href="#allocating-a-struct">struct allocation idiom</a>. |
| </p> |
| |
| <a href="xxx">go/src/pkg/os/file.go</a>: |
| <pre> |
| func NewFile(fd int, name string) *File { |
| if file < 0 { |
| return nil |
| } |
| return &File{fd, name, nil, 0} |
| } |
| </pre> |
| |
| <p>Packages that export only a single type sometimes |
| shorten <code>NewTypeName</code> to <code>New</code>; |
| for example, the vector constructor is |
| <code>vector.New</code>, not <code>vector.NewVector</code>. |
| </p> |
| |
| <p> |
| A type that is intended to be allocated |
| as part of a larger struct may have an <code>Init</code> method |
| that must be called explicitly. |
| Conventionally, the <code>Init</code> method returns |
| the object being initialized, to make the constructor trivial: |
| </p> |
| |
| <a href="xxx">go/src/pkg/container/vector/vector.go</a>: |
| <pre> |
| func New(len int) *Vector { |
| return new(Vector).Init(len) |
| } |
| </pre> |
| |
| <h3 id="zero-value">Make the zero value meaningful</h3> |
| |
| <p> |
| In Go, newly allocated memory and newly declared variables are zeroed. |
| If a type is intended to be allocated without using a constructor |
| (for example, as part of a larger struct or declared as a local variable), |
| define the meaning of the zero value and arrange for that meaning |
| to be useful. |
| </p> |
| |
| <p> |
| For example, <code>sync.Mutex</code> does not |
| have an explicit constructor or <code>Init</code> method. |
| Instead, the zero value for a <code>sync.Mutex</code> |
| is defined to be an unlocked mutex. |
| </p> |
| |
| <h2 id="interfaces">Interfaces</h2> |
| |
| <h3 id="accept-interface-values">Accept interface values</h3> |
| |
| buffered i/o takes a Reader, not an os.File. XXX |
| |
| <h3 id="return-interface-values">Return interface values</h3> |
| |
| <p> |
| If a type exists only to implement an interface |
| and has no exported methods beyond that interface, |
| there is no need to publish the type itself. |
| Instead, write a constructor that returns an interface value. |
| </p> |
| |
| <p> |
| For example, both <code>crc32.NewIEEE()</code> and <code>adler32.New()</code> |
| 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. |
| </p> |
| |
| <h3 id="">Use interface adapters to expand an implementation</h3> |
| |
| XXX |
| |
| <h3 id="">Use anonymous fields to incorporate an implementation</h3> |
| |
| XXX |
| |
| <h2>Data-Driven Programming</h2> |
| |
| <p> |
| tables |
| </p> |
| |
| <p> |
| XXX struct tags for marshalling. |
| template |
| eventually datafmt |
| </p> |
| |
| <h2>Concurrency</h2> |
| |
| <h3 id="share-memory">Share memory by communicating</h3> |
| |
| <p> |
| Do not communicate by sharing memory; |
| instead, share memory by communicating. |
| </p> |
| |
| <p> |
| XXX, more here. |
| </p> |
| |
| |
| <h2>Testing</h2> |
| |
| <h3 id="no-abort">Run tests to completion</h3> |
| |
| <p> |
| Tests should not stop early just because one case has misbehaved. |
| If at all possible, let tests continue, in order to characterize the |
| problem in more detail. |
| For example, it is more useful for a test to report that <code>isPrime</code> |
| gives the wrong answer for 2, 3, 5, and 7 (or for 2, 4, 8, and 16) than to report |
| that <code>isPrime</code> gives the wrong answer for 2 and therefore |
| no more tests were run. |
| </p> |
| |
| <h3 id="good-errors">Print useful errors when tests fail</h3> |
| |
| <p> |
| If a test fails, print a concise message explaining the context, |
| what happened, and what was expected. |
| Many testing environments encourage causing the |
| program to crash, but stack traces and core dumps |
| have low signal to noise ratios and require reconstructing |
| the situation from scratch. |
| The programmer who triggers the test failure may be someone |
| editing the code months later or even someone editing a different |
| package on which the code depends. |
| Time invested writing a good error message now pays off when |
| the test breaks later. |
| </p> |
| |
| <h3 id="data-driven-tests">Use data-driven tests</h3> |
| |
| <p> |
| Many tests reduce to running the same code multiple times, |
| with different input and expected output. |
| Instead of using cut and paste to write this code, |
| create a table of test cases and write a single test that |
| iterates over the table. |
| Once the table is written, you might find that it |
| serves well as input to multiple tests. For example, |
| a single table of encoded/decoded pairs can be |
| used by both <code>TestEncoder</code> and <code>TestDecoder</code>. |
| </p> |
| |
| <p> |
| This data-driven style dominates in the Go package tests. |
| <br> |
| <!-- search for for.*range here --> |
| </p> |
| |
| <h3 id="reflect.DeepEqual">Use reflect.DeepEqual to compare complex values</h3> |
| |
| <p> |
| The <code>reflect.DeepEqual</code> function tests |
| whether two complex data structures have equal values. |
| If a function returns a complex data structure, |
| <code>reflect.DeepEqual</code> combined with table-driven testing |
| makes it easy to check that the return value is |
| exactly as expected. |
| </p> |
| |
| </div> |
| </body> |
| </html> |