From b95048f38d2cd757de3bd762c8570aa43f4c17a3 Mon Sep 17 00:00:00 2001
From: Rob Pike
-
-Some formatting details remain. Very briefly:
+Some formatting details remain. Very briefly,
gofmt
will make the columns line up:
+gofmt
will make the columns line up.
@@ -101,7 +101,7 @@ All code in the libraries has been formatted with
gofmt
.
@@ -212,7 +212,7 @@ have a doc comment.
Doc comments work best as complete English sentences, which allow
a wide variety of automated presentations.
The first sentence should be a one-sentence summary that
-starts with the name being declared:
+starts with the name being declared.
@@ -366,7 +366,7 @@ Semicolons are never required at the top level. Also they are separators, not terminators, so they can be left off the last element of a statement or declaration list, a convenience -for one-linefuncs
and the like: +for one-linefuncs
and the like.@@ -378,7 +378,7 @@ func CopyInBackground(dst, src chan Item) {In fact, semicolons can be omitted at the end of any "StatementList" in the grammar, which includes things like cases in
switch
-statements: +statements.@@ -444,7 +444,7 @@ especially when the body contains a control statement such as aSince
if
andswitch
accept an initialization -statement, it's common to see one used to set up a local variable: +statement, it's common to see one used to set up a local variable.@@ -474,7 +474,7 @@ This is a example of a common situation where code must analyze a sequence of error possibilities. The code reads well if the successful flow of control runs down the page, eliminating error cases as they arise. Since error cases tend to end inreturn
-statements, the resulting code needs noelse
statements: +statements, the resulting code needs noelse
statements.@@ -493,10 +493,10 @@ codeUsing(f, d);For
-The Go
for
loop is similar to—but not the same as—C's. +The Gofor
loop is similar to—but not the same as—C's. It unifiesfor
andwhile
and there is nodo-while
. -There are three forms, only one of which has semicolons: +There are three forms, only one of which has semicolons.// Like a C for @@ -510,7 +510,7 @@ for { }-Short declarations make it easy to declare the index variable right in the loop: +Short declarations make it easy to declare the index variable right in the loop.
sum := 0; @@ -521,7 +521,7 @@ for i := 0; i < 10; i++ {If you're looping over an array, slice, string, or map a
range
clause can set -it all up for you: +it all up for you.var m map[string] int; @@ -553,7 +553,7 @@ character 語 starts at byte position 6Finally, since Go has no comma operator and
++
and--
are statements not expressions, if you want to run multiple variables in afor
-you should use parallel assignment: +you should use parallel assignment.// Reverse a @@ -570,9 +570,9 @@ The expressions need not be constants or even integers, the cases are evaluated top to bottom until a match is found, and if theswitch
has no expression it switches ontrue
. -It's therefore possible—and idiomatic—to write an +It's therefore possible—and idiomatic—to write anif
-else
-if
-else
-chain as aswitch
: +chain as aswitch
.@@ -591,7 +591,7 @@ func unhex(c byte) byte {There is no automatic fall through, but cases can be presented -in comma-separated lists: +in comma-separated lists.
func shouldEscape(c byte) bool { switch c { @@ -784,7 +784,7 @@ is defined to be an unlocked mutex.-The zero-value-is-useful property works transitively. Consider this type declaration: +The zero-value-is-useful property works transitively. Consider this type declaration.
@@ -797,7 +797,7 @@ type SyncedBuffer struct {Values of type
SyncedBuffer
are also ready to use immediately upon allocation or just declaration. In this snippet, bothp
andv
will work -correctly without further arrangement: +correctly without further arrangement.@@ -810,7 +810,7 @@ var v SyncedBuffer; // type SyncedBufferSometimes the zero value isn't good enough and an initializing constructor is necessary, as in this example derived from -package
os
: +packageos
.@@ -852,7 +852,7 @@ the storage associated with the variable survives after the function returns. In fact, taking the address of a composite literal allocates a fresh instance each time it is evaluated, -so we can combine these last two lines: +so we can combine these last two lines.@@ -872,7 +872,7 @@ order, with the missing ones left as their respective zero values. Thus we coulAs a limiting case, if a composite literal contains no fields at all, it creates -a zero value for the type. These two expressions are equivalent: +a zero value for the type. These two expressions are equivalent.
@@ -884,7 +884,7 @@ new(File) Composite literals can also be created for arrays, slices, and maps, with the field labels being indices or map keys as appropriate. In these examples, the initializations work regardless of the values ofEnoError
, -Eio
, andEinval
, as long as they are distinct: +Eio
, andEinval
, as long as they are distinct.@@ -928,7 +928,7 @@ structure, that is, a pointer to anil
slice value.These examples illustrate the difference between
new()
and -make()
: +make()
.@@ -959,7 +959,7 @@ To lay the foundation for that topic, here are a few words about arrays.There are major differences between the ways arrays work in Go and C. -In Go: +In Go,
[20]int
are distinct.
The value property can be useful but also expensive; if you want C-like behavior and efficiency, -you can pass a pointer to the array: +you can pass a pointer to the array.
@@ -1021,14 +1021,14 @@ func (file *File) Read(buf []byte) (n int, err os.Error)The method returns the number of bytes read and an error value, if any. To read into the first 32 bytes of a larger buffer -
b
, slice (here used as a verb) the buffer: +b
, slice (here used as a verb) the buffer.n, err := f.Read(buf[0:32]);Such slicing is common and efficient. In fact, leaving efficiency aside for -the moment, this snippet would also read the first 32 bytes of the buffer: +the moment, this snippet would also read the first 32 bytes of the buffer.
var n int; @@ -1044,7 +1044,7 @@ the moment, this snippet would also read the first 32 bytes of the buffer:The length of a slice may be changed as long as it still fits within -the limits of the underyling array; just assign it to a slice of +the limits of the underlying array; just assign it to a slice of itself. The capacity of a slice, accessible by the built-in function
cap
, reports the maximum length the slice may assume. Here is a function to append data to a slice. If the data @@ -1262,8 +1262,8 @@ map[string] int
If you want to control the default format for a custom type, all that's required is to define
-a method String() string
on the type. (Methods are the subject of the next
-section.) For our simple type T
, that might look like this.
+a method String() string
on the type.
+For our simple type T
, that might look like this.
func (t *T) String() string { @@ -1352,14 +1352,14 @@ func (p *ByteSlice) Write(data []byte) (n int, err os.Error) {+then the type
*ByteSlice
satisfies the standard interfaceio.Writer
, which is handy. For instance, we can -print into one: +print into one.var b ByteSlice; fmt.Fprintf(&b, "This hour has %d days\n", 7);-Notice that we must pass the address of a
-ByteSlice
+We pass the address of aByteSlice
because only*ByteSlice
satisfiesio.Writer
. The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be @@ -1372,38 +1372,167 @@ By the way, the idea of usingWrite
on a slice of bytes is implemented bybytes.Buffer
.Interfaces
+Interfaces and the interplay of types
- +// NewCBCDecrypter returns a reader that reads data +// from r and decrypts it using c in cipher block chaining (CBC) mode +// with the initialization vector iv. +func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader +
+NewECBDecrypter
and NewCBCReader
apply not
+just to one specific encryption algorithm and data source but to any
+implementation of the Cipher
interface and any
+io.Reader
. Because they return io.Reader
+interface values, replacing ECB
+encryption with CBC encryption is a localized change. The constructor
+calls must be edited, but because the code must treat the result only
+as an io.Reader
, it won't notice the difference.
+
Packages that export only a single type can
-shorten NewTypeName
to New
;
-the vector constructor is
-vector.New
, not vector.NewVector
.
-
-A type that is intended to be allocated
-as part of a larger struct may have an Init
method
-that must be called explicitly.
-Conventionally, the Init
method returns
-the object being initialized, to make the constructor trivial:
-
-func New(len int) *Vector { - return new(Vector).Init(len) -} -- -