From 22140a17a061fed02e3adab761d9b67fbc654155 Mon Sep 17 00:00:00 2001
From: Rob Pike
-Go is a new language. Although it's in the C family of languages
+Go is a new language. Although it's in the C family
it has some unusual properties that make effective Go programs
-different in character from programs in C, C++, or Java.
-To write Go well, it's important to understand its properties
+different in character from programs in existing languages.
+A straightforward translation of a C++ or Java program into Go
+is unlikely to produce a satisfactory result - Java programs
+are written in Java, not Go.
+On the other hand, thinking about the problem from a Go
+perspective could produce a successful but quite different
+program.
+In other words,
+to write Go well, it's important to understand its properties
and idioms.
+It's also important to know the established conventions for
+programming in Go, such as naming, formatting, program
+construction, and so on, so that programs you write
+will be easy for other Go programmers to understand.
-This document gives tips for writing clear, idiomatic Go code
-and points out common mistakes.
+This document gives tips for writing clear, idiomatic Go code.
It augments the language specification
and the tutorial, both of which you
should read first.
-The first step in learning to write good code is to read good code.
The Go package sources
are intended to serve not
only as the core library but also as examples of how to
-use the language. Read them and follow their example.
+use the language.
+If you have a question about how to approach a problem or how something
+might be implemented they can provide answers, ideas and
+background.
Formatting issues are the most contentious
but the least consequential.
-People adapt to different formatting styles,
-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,
-but to make them explicit here are some common points.
+People can adapt to different formatting styles
+but it's better if they don't have to, and
+less time is devoted to the topic
+if everyone adheres to the same style.
+The problem is how to approach this Utopia without a long
+prescriptive style guide.
-Use tabs, not spaces, for indentation.
+With Go we take a different, somewhat radical
+approach and let the machine
+take care of most formatting issues.
+A program,
-Let tools such as
-There should be no trailing white space at the end of lines.
+
-Go has no 80-character limit. Don't bother with fancy line
-wrapping just because a line is wider than a punched card.
-If a line is too long, indent with an extra tab.
+All code in the libraries has been formatted with Go does not require parentheses around the expression
-following the
+Some formatting details remain. Very briefly:
@@ -121,6 +170,7 @@ package regexp
+XXX no extra *s or boxes XXX
Consider how the package comment contributes to the appearance
of the
+XXX to the formatting section XXX
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.
@@ -210,7 +261,7 @@ or
Comments are text, not HTML; they contain no markup.
-Refrain from ASCII embellishment like *this* or /this/.
+Refrain from ASCII embellishment such as Introduction
Read good code
+Examples
Use tabs
-
gofmt
, reads a Go program
+and emits the source in a standard style of indentation
+and vertical alignment, retaining and if necessary
+reformatting comments.
+If you want to know how to handle some new layout
+situation, run gofmt
; if the answer doesn't
+seem right, fix the program (or file a bug), don't work around it.
Don't worry about columnation
-
gofmt
take care of lining things up.
+As an example, there's no need to spend time lining up
+the comments on the fields of a structure.
+Gofmt
will do that for you. Given the
+declaration
Trim trailing white space
+
+type T struct {
+ name string; // name of the object
+ value int; // its value
+}
+
gofmt
will make the columns line up:
Don't wrap lines
+
+type T struct {
+ name string; // name of the object
+ value int; // its value
+}
+
gofmt
.
+TODO
Omit parentheses in control structures
-for
, if
, range
,
-switch
, and return
keywords.
+
+
+
+gofmt
emits them by default.
+ Use spaces if you must.
+ if
,
+ for
, switch
) do not have parentheses in
+ their syntax.
+ Also, the operator precedence hierarchy is shorter and clearer, so
+
+x<<8 + y<<16
+
+ means what the spacing implies.
+ Commentary
+
Use line comments
godoc
page for the package. Don't just
echo the doc comments for the components. The package comment
@@ -175,6 +225,7 @@ a wider variety of automated presentations.
Avoid ASCII Art
*this*
or /this/
.
Use grouping to organize declarations
@@ -292,7 +343,7 @@ Similarly, once.Do
is as precise and evocative as
once.DoOrWaitUntilDone
, and once.Do(f)
reads
better than once.DoOrWaitUntilDone(f)
.
Encoding small essays into function names is not Go style;
-clear names with good documentation is.
+using clear names supported by good documentation is.
Reader
,
+XXX permits interfaces String() not ToString() XXX
A few method names—Read
, Write
, Close
, Flush
, String
—have
canonical signatures and meanings. To avoid confusion,
don't give your method one of those names unless it
@@ -334,14 +386,16 @@ or n
and cnt
.
A struct literal is an expression that creates a new instance each time it is evaluated. The address of such -an expression therefore points to a fresh instance each time. +an expression points to a fresh instance each time. Use such expressions to avoid the repetition of filling out a data structure.
length := Point{x, y}.Abs(); ++
// Prepare RPCMessage to send to server rpc := &RPCMessage { Version: 1, @@ -354,11 +408,6 @@ rpc := &RPCMessage { };-
-Array, slice, and map literals behave similarly, although it is -unusual to need the address of a slice or map. -
-@@ -387,7 +436,8 @@ codeUsing(f);-Go's
@@ -483,7 +533,7 @@ there may be more later. 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, +Also, error cases tend to end inswitch
is more general than C's. -When anif
-else if
-else
chain has three or more bodies, +When anif
-else
-if
-else
+chain has three or more bodies, or anif
condition has a long list of alternatives, it will be clearer if rewritten as aswitch
.return
statements, so that there is no need for an explicit else. @@ -566,7 +616,7 @@ func NewFile(fd int, name string) *File { }
Packages that export only a single type sometimes +
Packages that export only a single type can
shorten NewTypeName
to New
;
the vector constructor is
vector.New
, not vector.NewVector
.
@@ -670,9 +720,14 @@ 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 isPrime
-gives the wrong answer for 2, 3, 5, and 7 (or for 2, 4, 8, and 16) than to report
-that isPrime
gives the wrong answer for 2 and therefore
+gives the wrong answer for 4, 8, 16 and 32 than to report
+that isPrime
gives the wrong answer for 4 and therefore
no more tests were run.
+XXX
+test bottom up
+test runs top to bottom
+how to use gotest
+XXX