From 22140a17a061fed02e3adab761d9b67fbc654155 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Wed, 19 Aug 2009 13:24:24 -0700 Subject: [PATCH] start of a rewrite with a different tone R=rsc DELTA=131 (61 added, 6 deleted, 64 changed) OCL=33488 CL=33532 --- doc/effective_go.html | 147 +++++++++++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 46 deletions(-) diff --git a/doc/effective_go.html b/doc/effective_go.html index fc777c09515..536adee969c 100644 --- a/doc/effective_go.html +++ b/doc/effective_go.html @@ -2,29 +2,41 @@

Introduction

-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.

-

Read good code

+

Examples

-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.

@@ -33,50 +45,87 @@ use the language. Read them and follow their example.

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

-

-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, 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

-

-Let tools such as 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
+}
+

-There should be no trailing white space at the end of lines. +gofmt will make the columns line up:

-

Don't wrap lines

+
+type T struct {
+    name    string; // name of the object
+    value   int;    // its value
+}
+

-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 gofmt. +TODO

-

Omit parentheses in control structures

-

Go does not require parentheses around the expression -following the for, if, range, -switch, and return keywords. +

+Some formatting details remain. Very briefly:

+
+
Indentation
+
We use tabs for indentation and gofmt emits them by default. + Use spaces if you must. +
+
Line length
+
+ Go has no line length limit. Don't worry about overflowing a punched card. + If a line feels too long, wrap it and indent with an extra tab. +
+
Parentheses
+
+ Go needs fewer parentheses: control structures (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

@@ -121,6 +170,7 @@ package regexp

+XXX no extra *s or boxes XXX Consider how the package comment contributes to the appearance of the 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

+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 *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.

Use the -er convention for interface names

@@ -306,6 +357,7 @@ the method name plus the -er suffix: Reader,

Use canonical names

+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. -

-

Use parallel assignment to slice a buffer

@@ -387,7 +436,8 @@ codeUsing(f);
 
 

Go's switch is more general than C's. -When an if-else if-else chain has three or more bodies, +When an if-else-if-else +chain has three or more bodies, or an if condition has a long list of alternatives, it will be clearer if rewritten as a switch.

@@ -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 in 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

Print useful errors when tests fail