summaryrefslogtreecommitdiff
path: root/doc/effective_go.html
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-05-14 18:39:35 +0200
committerMichael Stapelberg <michael@stapelberg.de>2013-05-14 18:39:35 +0200
commitefcc50dfdc94c82ee0292bf71992ecb7c0123061 (patch)
tree17dca99d1dc7fc4e9fe49c2cf6a99d337d4c039f /doc/effective_go.html
parent04b08da9af0c450d645ab7389d1467308cfc2db8 (diff)
downloadgolang-efcc50dfdc94c82ee0292bf71992ecb7c0123061.tar.gz
Imported Upstream version 1.1upstream/1.1
Diffstat (limited to 'doc/effective_go.html')
-rw-r--r--doc/effective_go.html758
1 files changed, 527 insertions, 231 deletions
diff --git a/doc/effective_go.html b/doc/effective_go.html
index e02694add..1b3168683 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -403,8 +403,10 @@ if owner != user {
<p>
By convention, one-method interfaces are named by
-the method name plus the -er suffix: <code>Reader</code>,
-<code>Writer</code>, <code>Formatter</code> etc.
+the method name plus an -er suffix or similar modification
+to construct an agent noun: <code>Reader</code>,
+<code>Writer</code>, <code>Formatter</code>,
+<code>CloseNotifier</code> etc.
</p>
<p>
@@ -696,10 +698,18 @@ for _, value := range array {
</pre>
<p>
+The blank identifier has many uses, as described in <a href="#blank">a later section</a>.
+
+<p>
For strings, the <code>range</code> does more work for you, breaking out individual
Unicode code points by parsing the UTF-8.
Erroneous encodings consume one byte and produce the
-replacement rune U+FFFD. The loop
+replacement rune U+FFFD.
+(The name (with associated builtin type) <code>rune</code> is Go terminology for a
+single Unicode code point.
+See <a href="http://golang.org/ref/spec#Rune_literals">the language specification</a>
+for details.)
+The loop
</p>
<pre>
for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding
@@ -797,6 +807,8 @@ func Compare(a, b []byte) int {
}
</pre>
+<h2 id="type_switch">Type switch</h2>
+
<p>
A switch can also be used to discover the dynamic type of an interface
variable. Such a <em>type switch</em> uses the syntax of a type
@@ -831,8 +843,8 @@ case *int:
One of Go's unusual features is that functions and methods
can return multiple values. This form can be used to
improve on a couple of clumsy idioms in C programs: in-band
-error returns (such as <code>-1</code> for <code>EOF</code>)
-and modifying an argument.
+error returns such as <code>-1</code> for <code>EOF</code>
+and modifying an argument passed by address.
</p>
<p>
@@ -841,7 +853,8 @@ error code secreted away in a volatile location.
In Go, <code>Write</code>
can return a count <i>and</i> an error: &ldquo;Yes, you wrote some
bytes but not all of them because you filled the device&rdquo;.
-The signature of <code>File.Write</code> in package <code>os</code> is:
+The signature of the <code>Write</code> method on files from
+package <code>os</code> is:
</p>
<pre>
@@ -1208,7 +1221,7 @@ It creates slices, maps, and channels only, and it returns an <em>initialized</e
(not <em>zeroed</em>)
value of type <code>T</code> (not <code>*T</code>).
The reason for the distinction
-is that these three types are, under the covers, references to data structures that
+is that these three types represent, under the covers, references to data structures that
must be initialized before use.
A slice, for example, is a three-item descriptor
containing a pointer to the data (inside an array), the length, and the
@@ -1253,7 +1266,8 @@ v := make([]int, 100)
<p>
Remember that <code>make</code> applies only to maps, slices and channels
and does not return a pointer.
-To obtain an explicit pointer allocate with <code>new</code>.
+To obtain an explicit pointer allocate with <code>new</code> or take the address
+of a variable explicitly.
</p>
<h3 id="arrays">Arrays</h3>
@@ -1300,7 +1314,8 @@ x := Sum(&amp;array) // Note the explicit address-of operator
</pre>
<p>
-But even this style isn't idiomatic Go. Slices are.
+But even this style isn't idiomatic Go.
+Use slices instead.
</p>
<h3 id="slices">Slices</h3>
@@ -1312,9 +1327,9 @@ dimension such as transformation matrices, most array programming in
Go is done with slices rather than simple arrays.
</p>
<p>
-Slices are <i>reference types</i>, which means that if you assign one
-slice to another, both refer to the same underlying array. For
-instance, if a function takes a slice argument, changes it makes to
+Slices hold references to an underlying array, and if you assign one
+slice to another, both refer to the same array.
+If a function takes a slice argument, changes it makes to
the elements of the slice will be visible to the caller, analogous to
passing a pointer to the underlying array. A <code>Read</code>
function can therefore accept a slice argument rather than a pointer
@@ -1391,19 +1406,87 @@ design, though, we need a little more information, so we'll return
to it later.
</p>
+<h3 id="two_dimensional_slices">Two-dimensional slices</h3>
+
+<p>
+Go's arrays and slices are one-dimensional.
+To create the equivalent of a 2D array or slice, it is necessary to define an array-of-arrays
+or slice-of-slices, like this:
+</p>
+
+<pre>
+type Transform [3][3]float64 // A 3x3 array, really an array of arrays.
+type LinesOfText [][]byte // A slice of byte slices.
+</pre>
+
+<p>
+Because slices are variable-length, it is possible to have each inner
+slice be a different length.
+That can be a common situation, as in our <code>LinesOfText</code>
+example: each line has an independent length.
+</p>
+
+<pre>
+text := LinesOfText{
+ []byte("Now is the time"),
+ []byte("for all good gophers"),
+ []byte("to bring some fun to the party."),
+}
+</pre>
+
+<p>
+Sometimes it's necessary to allocate a 2D slice, a situation that can arise when
+processing scan lines of pixels, for instance.
+There are two ways to achieve this.
+One is to allocate each slice independently; the other
+is to allocate a single array and point the individual slices into it.
+Which to use depends on your application.
+If the slices might grow or shrink, they should be allocated independently
+to avoid overwriting the next line; if not, it can be more efficient to construct
+the object with a single allocation.
+For reference, here are sketches of the two methods.
+First, a line a time:
+</p>
+
+<pre>
+// Allocate the top-level slice.
+picture := make([][]uint8, YSize) // One row per unit of y.
+// Loop over the rows, allocating the slice for each row.
+for i := range picture {
+ picture[i] = make([]uint8, XSize)
+}
+</pre>
+
+<p>
+And now as one allocation, sliced into lines:
+</p>
+
+<pre>
+// Allocate the top-level slice, the same as before.
+picture := make([][]uint8, YSize) // One row per unit of y.
+// Allocate one large slice to hold all the pixels.
+pixels := make([]uint8, XSize*YSize) // Has type []uint8 even though picture is [][]uint8.
+// Loop over the rows, slicing each row from the front of the remaining pixels slice.
+for i := range picture {
+ picture[i], pixels = pixels[:XSize], pixels[XSize:]
+}
+</pre>
<h3 id="maps">Maps</h3>
<p>
-Maps are a convenient and powerful built-in data structure to associate
-values of different types.
+Maps are a convenient and powerful built-in data structure that associate
+values of one type (the <em>key</em>) with values of another type
+(the <em>element</em> or <em>value</em>)
The key can be of any type for which the equality operator is defined,
such as integers,
floating point and complex numbers,
strings, pointers, interfaces (as long as the dynamic type
-supports equality), structs and arrays. Slices cannot be used as map keys,
+supports equality), structs and arrays.
+Slices cannot be used as map keys,
because equality is not defined on them.
-Like slices, maps are a reference type. If you pass a map to a function
+Like slices, maps hold references to an underlying data structure.
+If you pass a map to a function
that changes the contents of the map, the changes will be visible
in the caller.
</p>
@@ -1453,7 +1536,7 @@ if attended[person] { // will be false if person is not in the map
<p>
Sometimes you need to distinguish a missing entry from
a zero value. Is there an entry for <code>"UTC"</code>
-or is that zero value because it's not in the map at all?
+or is that the empty string because it's not in the map at all?
You can discriminate with a form of multiple assignment.
</p>
<pre>
@@ -1480,10 +1563,8 @@ func offset(tz string) int {
</pre>
<p>
To test for presence in the map without worrying about the actual value,
-you can use the blank identifier (<code>_</code>).
-The blank identifier can be assigned or declared with any value of any type, with the
-value discarded harmlessly. For testing just presence in a map, use the blank
-identifier in place of the usual variable for the value.
+you can use the <a href="#blank">blank identifier</a> (<code>_</code>)
+in place of the usual variable for the value.
</p>
<pre>
_, present := timeZone[tz]
@@ -1491,7 +1572,7 @@ _, present := timeZone[tz]
<p>
To delete a map entry, use the <code>delete</code>
built-in function, whose arguments are the map and the key to be deleted.
-It's safe to do this this even if the key is already absent
+It's safe to do this even if the key is already absent
from the map.
</p>
<pre>
@@ -1524,8 +1605,7 @@ fmt.Println("Hello", 23)
fmt.Println(fmt.Sprint("Hello ", 23))
</pre>
<p>
-As mentioned in
-the <a href="http://tour.golang.org">Tour</a>, <code>fmt.Fprint</code>
+The formatted print functions <code>fmt.Fprint</code>
and friends take as a first argument any object
that implements the <code>io.Writer</code> interface; the variables <code>os.Stdout</code>
and <code>os.Stderr</code> are familiar instances.
@@ -1591,8 +1671,10 @@ map[string] int{"CST":-21600, "PST":-28800, "EST":-18000, "UTC":0, "MST":-25200}
<p>
(Note the ampersands.)
That quoted string format is also available through <code>%q</code> when
-applied to a value of type <code>string</code> or <code>[]byte</code>;
-the alternate format <code>%#q</code> will use backquotes instead if possible.
+applied to a value of type <code>string</code> or <code>[]byte</code>.
+The alternate format <code>%#q</code> will use backquotes instead if possible.
+(The <code>%q</code> format also applies to integers and runes, producing a
+single-quoted rune constant.)
Also, <code>%x</code> works on strings, byte arrays and byte slices as well as
on integers, generating a long hexadecimal string, and with
a space in the format (<code>%&nbsp;x</code>) it puts spaces between the bytes.
@@ -1632,10 +1714,45 @@ the receiver for <code>String</code> must be of value type; this example used a
that's more efficient and idiomatic for struct types.
See the section below on <a href="#pointers_vs_values">pointers vs. value receivers</a> for more information.)
</p>
+
<p>
Our <code>String</code> method is able to call <code>Sprintf</code> because the
-print routines are fully reentrant and can be used recursively.
-We can even go one step further and pass a print routine's arguments directly to another such routine.
+print routines are fully reentrant and can be wrapped this way.
+There is one important detail to understand about this approach,
+however: don't construct a <code>String</code> method by calling
+<code>Sprintf</code> in a way that will recur into your <code>String</code>
+method indefinitely. This can happen if the <code>Sprintf</code>
+call attempts to print the receiver directly as a string, which in
+turn will invoke the method again. It's a common and easy mistake
+to make, as this example shows.
+</p>
+
+<pre>
+type MyString string
+
+func (m MyString) String() string {
+ return fmt.Sprintf("MyString=%s", m) // Error: will recur forever.
+}
+</pre>
+
+<p>
+It's also easy to fix: convert the argument to the basic string type, which does not have the
+method.
+</p>
+
+<pre>
+type MyString string
+func (m MyString) String() string {
+ return fmt.Sprintf("MyString=%s", string(m)) // OK: note conversion.
+}
+</pre>
+
+<p>
+In the <a href="#initialization">initialization section</a> we'll see another technique that avoids this recursion.
+</p>
+
+<p>
+Another printing technique is to pass a print routine's arguments directly to another such routine.
The signature of <code>Printf</code> uses the type <code>...interface{}</code>
for its final argument to specify that an arbitrary number of parameters (of arbitrary type)
can appear after the format.
@@ -1690,7 +1807,7 @@ is different from our custom <code>Append</code> function above.
Schematically, it's like this:
</p>
<pre>
-func append(slice []<i>T</i>, elements...T) []<i>T</i>
+func append(slice []<i>T</i>, elements ...<i>T</i>) []<i>T</i>
</pre>
<p>
where <i>T</i> is a placeholder for any given type. You can't
@@ -1738,7 +1855,7 @@ would be wrong; <code>y</code> is not of type <code>int</code>.
Although it doesn't look superficially very different from
initialization in C or C++, initialization in Go is more powerful.
Complex structures can be built during initialization and the ordering
-issues between initialized objects in different packages are handled
+issues among initialized objects, even among different packages, are handled
correctly.
</p>
@@ -1748,7 +1865,7 @@ correctly.
Constants in Go are just that&mdash;constant.
They are created at compile time, even when defined as
locals in functions,
-and can only be numbers, strings or booleans.
+and can only be numbers, characters (runes), strings or booleans.
Because of the compile-time restriction, the expressions
that define them must be constant expressions,
evaluatable by the compiler. For instance,
@@ -1766,9 +1883,11 @@ sets of values.
</p>
{{code "/doc/progs/eff_bytesize.go" `/^type ByteSize/` `/^\)/`}}
<p>
-The ability to attach a method such as <code>String</code> to a
-type makes it possible for such values to format themselves
-automatically for printing, even as part of a general type.
+The ability to attach a method such as <code>String</code> to any
+user-defined type makes it possible for arbitrary values to format themselves
+automatically for printing.
+Although you'll see it most often applied to structs, this technique is also useful for
+scalar types such as floating-point types like <code>ByteSize</code>.
</p>
{{code "/doc/progs/eff_bytesize.go" `/^func.*ByteSize.*String/` `/^}/`}}
<p>
@@ -1777,13 +1896,13 @@ while <code>ByteSize(1e13)</code> prints as <code>9.09TB</code>.
</p>
<p>
-Note that it's fine to call <code>Sprintf</code> and friends in the
-implementation of <code>String</code> methods, but beware of
-recurring into the <code>String</code> method through the nested
-<code>Sprintf</code> call using a string format
-(<code>%s</code>, <code>%q</code>, <code>%v</code>, <code>%x</code> or <code>%X</code>).
-The <code>ByteSize</code> implementation of <code>String</code> is safe
-because it calls <code>Sprintf</code> with <code>%f</code>.
+The use here of <code>Sprintf</code>
+to implement <code>ByteSize</code>'s <code>String</code> method is safe
+(avoids recurring indefinitely) not because of a conversion but
+because it calls <code>Sprintf</code> with <code>%f</code>,
+which is not a string format: <code>Sprintf</code> will only call
+the <code>String</code> method when it wants a string, and <code>%f</code>
+wants a floating-point value.
</p>
<h3 id="variables">Variables</h3>
@@ -1837,7 +1956,8 @@ func init() {
<h3 id="pointers_vs_values">Pointers vs. Values</h3>
<p>
-Methods can be defined for any named type that is not a pointer or an interface;
+As we saw with <code>ByteSize</code>,
+methods can be defined for any named type (except a pointer or an interface);
the receiver does not have to be a struct.
</p>
<p>
@@ -1898,7 +2018,7 @@ modifications to be discarded.
</p>
<p>
By the way, the idea of using <code>Write</code> on a slice of bytes
-is implemented by <code>bytes.Buffer</code>.
+is central to the implementation of <code>bytes.Buffer</code>.
</p>
<h2 id="interfaces_and_types">Interfaces and other types</h2>
@@ -1941,10 +2061,8 @@ func (s Sequence) String() string {
}
</pre>
<p>
-The conversion causes <code>s</code> to be treated as an ordinary slice
-and therefore receive the default formatting.
-Without the conversion, <code>Sprint</code> would find the
-<code>String</code> method of <code>Sequence</code> and recur indefinitely.
+This method is another example of the conversion technique for calling
+<code>Sprintf</code> safely from a <code>String</code> method.
Because the two types (<code>Sequence</code> and <code>[]int</code>)
are the same if we ignore the type name, it's legal to convert between them.
The conversion doesn't create a new value, it just temporarily acts
@@ -1976,6 +2094,91 @@ and <code>[]int</code>), each of which does some part of the job.
That's more unusual in practice but can be effective.
</p>
+<h3 id="interface_conversions">Interface conversions and type assertions</h3>
+
+<p>
+<a href="#type_switch">Type switches</a> are a form of conversion: they take an interface and, for
+each case in the switch, in a sense convert it to the type of that case.
+Here's a simplified version of how the code under <code>fmt.Printf</code> turns a value into
+a string using a type switch.
+If it's already a string, we want the actual string value held by the interface, while if it has a
+<code>String</code> method we want the result of calling the method.
+</p>
+
+<pre>
+type Stringer interface {
+ String() string
+}
+
+var value interface{} // Value provided by caller.
+switch str := value.(type) {
+case string:
+ return str
+case Stringer:
+ return str.String()
+}
+</pre>
+
+<p>
+The first case finds a concrete value; the second converts the interface into another interface.
+It's perfectly fine to mix types this way.
+</p>
+
+<p>
+What if there's only one type we care about? If we know the value holds a <code>string</code>
+and we just want to extract it?
+A one-case type switch would do, but so would a <em>type assertion</em>.
+A type assertion takes an interface value and extracts from it a value of the specified explicit type.
+The syntax borrows from the clause opening a type switch, but with an explicit
+type rather than the <code>type</code> keyword:
+
+<pre>
+value.(typeName)
+</pre>
+
+<p>
+and the result is a new value with the static type <code>typeName</code>.
+That type must either be the concrete type held by the interface, or a second interface
+type that the value can be converted to.
+To extract the string we know is in the value, we could write:
+</p>
+
+<pre>
+str := value.(string)
+</pre>
+
+<p>
+But if it turns out that the value does not contain a string, the program will crash with a run-time error.
+To guard against that, use the "comma, ok" idiom to test, safely, whether the value is a string:
+</p>
+
+<pre>
+str, ok := value.(string)
+if ok {
+ fmt.Printf("string value is: %q\n", str)
+} else {
+ fmt.Printf("value is not a string\n")
+}
+</pre>
+
+<p>
+If the type assertion fails, <code>str</code> will still exist and be of type string, but it will have
+the zero value, an empty string.
+</p>
+
+<p>
+As an illustration of the capability, here's an <code>if</code>-<code>else</code>
+statement that's equivalent to the type switch that opened this section.
+</p>
+
+<pre>
+if str, ok := value.(string); ok {
+ return str
+} else if str, ok := value.(Stringer); ok {
+ return str.String()
+}
+</pre>
+
<h3 id="generality">Generality</h3>
<p>
If a type exists only to implement an interface
@@ -2133,9 +2336,7 @@ It's easy to write a function to print the arguments.
</p>
<pre>
func ArgServer() {
- for _, s := range os.Args {
- fmt.Println(s)
- }
+ fmt.Println(os.Args)
}
</pre>
<p>
@@ -2171,9 +2372,7 @@ to have the right signature.
<pre>
// Argument server.
func ArgServer(w http.ResponseWriter, req *http.Request) {
- for _, s := range os.Args {
- fmt.Fprintln(w, s)
- }
+ fmt.Fprintln(w, os.Args)
}
</pre>
<p>
@@ -2202,6 +2401,196 @@ a channel, and a function, all because interfaces are just sets of
methods, which can be defined for (almost) any type.
</p>
+<h2 id="blank">The blank identifier</h2>
+
+<p>
+We've mentioned the blank identifier a couple of times now, in the context of
+<a href="#for"><code>for</code> <code>range</code> loops</a>
+and <a href="#maps">maps</a>.
+The blank identifier can be assigned or declared with any value of any type, with the
+value discarded harmlessly.
+It's a bit like writing to the Unix <code>/dev/null</code> file:
+it represents a write-only value
+to be used as a place-holder
+where a variable is needed but the actual value is irrelevant.
+It has uses beyond those we've seen already.
+</p>
+
+<h3 id="blank_assign">The blank identifier in multiple assignment</h3>
+
+<p>
+The use of a blank identifier in a <code>for</code> <code>range</code> loop is a
+special case of a general situation: multiple assignment.
+<p>
+If an assignment requires multiple values on the left side,
+but one of the values will not be used by the program,
+a blank identifier on the left-hand-side of
+the assignment avoids the need
+to create a dummy variable and makes it clear that the
+value is to be discarded.
+For instance, when calling a function that returns
+a value and an error, but only the error is important,
+use the blank identifier to discard the irrelevant value.
+</p>
+
+<pre>
+if _, err := os.Stat(path); os.IsNotExist(err) {
+ fmt.Printf("%s does not exist\n", path)
+}
+</pre>
+
+<p>
+Occasionally you'll see code that discards the error value in order
+to ignore the error; this is terrible practice. Always check error returns;
+they're provided for a reason.
+</p>
+
+<pre>
+// Bad! This code will crash if path does not exist.
+fi, _ := os.Stat(path)
+if fi.IsDir() {
+ fmt.Printf("%s is a directory\n", path)
+}
+</pre>
+
+<h3 id="blank_unused">Unused imports and variables</h3>
+
+<p>
+It is an error to import a package or to declare a variable without using it.
+Unused imports bloat the program and slow compilation,
+while a variable that is initialized but not used is at least
+a wasted computation and perhaps indicative of a
+larger bug.
+When a program is under active development, however,
+unused imports and variables often arise and it can
+be annoying to delete them just to have the compilation proceed,
+only to have them be needed again later.
+The blank identifier provides a workaround.
+</p>
+<p>
+This half-written program has two unused imports
+(<code>fmt</code> and <code>io</code>)
+and an unused variable (<code>fd</code>),
+so it will not compile, but it would be nice to see if the
+code so far is correct.
+</p>
+{{code "/doc/progs/eff_unused1.go" `/package/` `$`}}
+<p>
+To silence complaints about the unused imports, use a
+blank identifier to refer to a symbol from the imported package.
+Similarly, assigning the unused variable <code>fd</code>
+to the blank identifier will silence the unused variable error.
+This version of the program does compile.
+</p>
+{{code "/doc/progs/eff_unused2.go" `/package/` `$`}}
+
+<p>
+By convention, the global declarations to silence import errors
+should come right after the imports and be commented,
+both to make them easy to find and as a reminder to clean things up later.
+</p>
+
+<h3 id="blank_import">Import for side effect</h3>
+
+<p>
+An unused import like <code>fmt</code> or <code>io</code> in the
+previous example should eventually be used or removed:
+blank assignments identify code as a work in progress.
+But sometimes it is useful to import a package only for its
+side effects, without any explicit use.
+For example, during its <code>init</code> function,
+the <code><a href="/pkg/net/http/pprof/">net/http/pprof</a></code>
+package registers HTTP handlers that provide
+debugging information. It has an exported API, but
+most clients need only the handler registration and
+access the data through a web page.
+To import the package only for its side effects, rename the package
+to the blank identifier:
+</p>
+<pre>
+import _ "net/http/pprof"
+</pre>
+<p>
+This form of import makes clear that the package is being
+imported for its side effects, because there is no other possible
+use of the package: in this file, it doesn't have a name.
+(If it did, and we didn't use that name, the compiler would reject the program.)
+</p>
+
+<h3 id="blank_implements">Interface checks</h3>
+
+<p>
+As we saw in the discussion of <a href="#interfaces_and_types">interfaces</a> above,
+a type need not declare explicitly that it implements an interface.
+Instead, a type implements the interface just by implementing the interface's methods.
+In practice, most interface conversions are static and therefore checked at compile time.
+For example, passing an <code>*os.File</code> to a function
+expecting an <code>io.Reader</code> will not compile unless
+<code>*os.File</code> implements the <code>io.Reader</code> interface.
+</p>
+
+<p>
+Some interface checks do happen at run-time, though.
+One instance is in the <code><a href="/pkg/encoding/json/">encoding/json</a></code>
+package, which defines a <code><a href="/pkg/encoding/json/#Marshaler">Marshaler</a></code>
+interface. When the JSON encoder receives a value that implements that interface,
+the encoder invokes the value's marshaling method to convert it to JSON
+instead of doing the standard conversion.
+The encoder checks this property at run time with a <a href="interface_conversions">type assertion</a> like:
+</p>
+
+<pre>
+m, ok := val.(json.Marshaler)
+</pre>
+
+<p>
+If it's necessary only to ask whether a type implements an interface, without
+actually using the interface itself, perhaps as part of an error check, use the blank
+identifier to ignore the type-asserted value:
+</p>
+
+<pre>
+if _, ok := val.(json.Marshaler); ok {
+ fmt.Printf("value %v of type %T implements json.Marshaler\n", val, val)
+}
+</pre>
+
+<p>
+One place this situation arises is when it is necessary to guarantee within the package implementing the type that
+it actually satisfies the interface.
+If a type—for example,
+<code><a href="/pkg/encoding/json/#RawMessage">json.RawMessage</a></code>—needs
+a custom its JSON representation, it should implement
+<code>json.Marshaler</code>, but there are no static conversions that would
+cause the compiler to verify this automatically.
+If the type inadvertently fails to satisfy the interface, the JSON encoder will still work,
+but will not use the custom implementation.
+To guarantee that the implementation is correct,
+a global declaration using the blank identifier can be used in the package:
+</p>
+<pre>
+var _ json.Marshaler = (*RawMessage)(nil)
+</pre>
+<p>
+In this declaration, the assignment involving a conversion of a
+<code>*RawMessage</code> to a <code>Marshaler</code>
+requires that <code>*RawMessage</code> implements <code>Marshaler</code>,
+and that property will be checked at compile time.
+Should the <code>json.Marshaler</code> interface change, this package
+will no longer compile and we will be on notice that it needs to be updated.
+</p>
+
+<p>
+The appearance of the blank identifier in this construct indicates that
+the declaration exists only for the type checking,
+not to create a variable.
+Don't do this for every type that satisfies an interface, though.
+By convention, such declarations are only used
+when there are no static conversions already present in the code,
+which is a rare event.
+</p>
+
+
<h2 id="embedding">Embedding</h2>
<p>
@@ -2328,8 +2717,8 @@ log to the <code>Job</code>:
job.Log("starting now...")
</pre>
<p>
-The <code>Logger</code> is a regular field of the struct and we can initialize
-it in the usual way with a constructor,
+The <code>Logger</code> is a regular field of the <code>Job</code> struct,
+so we can initialize it in the usual way inside the constructor for <code>Job</code>, like this,
</p>
<pre>
func NewJob(command string, logger *log.Logger) *Job {
@@ -2344,10 +2733,12 @@ job := &amp;Job{command, log.New(os.Stderr, "Job: ", log.Ldate)}
</pre>
<p>
If we need to refer to an embedded field directly, the type name of the field,
-ignoring the package qualifier, serves as a field name. If we needed to access the
+ignoring the package qualifier, serves as a field name, as it did
+in the <code>Read</code> method of our <code>ReaderWriter</code> struct.
+Here, if we needed to access the
<code>*log.Logger</code> of a <code>Job</code> variable <code>job</code>,
-we would write <code>job.Logger</code>.
-This would be useful if we wanted to refine the methods of <code>Logger</code>.
+we would write <code>job.Logger</code>,
+which would be useful if we wanted to refine the methods of <code>Logger</code>.
</p>
<pre>
func (job *Job) Logf(format string, args ...interface{}) {
@@ -2463,7 +2854,8 @@ completion. For that, we need channels.
<h3 id="channels">Channels</h3>
<p>
-Like maps, channels are a reference type and are allocated with <code>make</code>.
+Like maps, channels are allocated with <code>make</code>, and
+the resulting value acts as a reference to an underlying data structure.
If an optional integer parameter is provided, it sets the buffer size for the channel.
The default is zero, for an unbuffered or synchronous channel.
</p>
@@ -2473,7 +2865,7 @@ cj := make(chan int, 0) // unbuffered channel of integers
cs := make(chan *os.File, 100) // buffered channel of pointers to Files
</pre>
<p>
-Channels combine communication&mdash;the exchange of a value&mdash;with
+Unbuffered channels combine communication&mdash;the exchange of a value&mdash;with
synchronization&mdash;guaranteeing that two calculations (goroutines) are in
a known state.
</p>
@@ -2503,18 +2895,26 @@ means waiting until some receiver has retrieved a value.
<p>
A buffered channel can be used like a semaphore, for instance to
limit throughput. In this example, incoming requests are passed
-to <code>handle</code>, which sends a value into the channel, processes
-the request, and then receives a value from the channel.
+to <code>handle</code>, which receives a value from the channel, processes
+the request, and then sends a value back to the channel
+to ready the "semaphore" for the next consumer.
The capacity of the channel buffer limits the number of
-simultaneous calls to <code>process</code>.
+simultaneous calls to <code>process</code>,
+so during initialization we prime the channel by filling it to capacity.
</p>
<pre>
var sem = make(chan int, MaxOutstanding)
func handle(r *Request) {
- sem &lt;- 1 // Wait for active queue to drain.
- process(r) // May take a long time.
- &lt;-sem // Done; enable next request to run.
+ &lt;-sem // Wait for active queue to drain.
+ process(r) // May take a long time.
+ sem &lt;- 1 // Done; enable next request to run.
+}
+
+func init() {
+ for i := 0; i < MaxOutstanding; i++ {
+ sem &lt;- 1
+ }
}
func Serve(queue chan *Request) {
@@ -2524,8 +2924,37 @@ func Serve(queue chan *Request) {
}
}
</pre>
+
+<p>
+Because data synchronization occurs on a receive from a channel
+(that is, the send "happens before" the receive; see
+<a href="/ref/mem">The Go Memory Model</a>),
+acquisition of the semaphore must be on a channel receive, not a send.
+</p>
+
+<p>
+This design has a problem, though: <code>Serve</code>
+creates a new goroutine for
+every incoming request, even though only <code>MaxOutstanding</code>
+of them can run at any moment.
+As a result, the program can consume unlimited resources if the requests come in too fast.
+We can address that deficiency by changing <code>Serve</code> to
+gate the creation of the goroutines.
+</p>
+
+<pre>
+func Serve(queue chan *Request) {
+ for req := range queue {
+ &lt;-sem
+ go func() {
+ process(req)
+ sem &lt;- 1
+ }()
+ }
+}</pre>
+
<p>
-Here's the same idea implemented by starting a fixed
+Another solution that manages resources well is to start a fixed
number of <code>handle</code> goroutines all reading from the request
channel.
The number of goroutines limits the number of simultaneous
@@ -2534,6 +2963,7 @@ This <code>Serve</code> function also accepts a channel on which
it will be told to exit; after launching the goroutines it blocks
receiving from that channel.
</p>
+
<pre>
func handle(queue chan *Request) {
for r := range queue {
@@ -2669,6 +3099,17 @@ of logical CPUs on the local machine.
Again, this requirement is expected to be retired as the scheduling and run-time improve.
</p>
+<p>
+Be sure not to confuse the ideas of concurrency—structuring a program
+as independently executing components—and parallelism—executing
+calculations in parallel for efficiency on multiple CPUs.
+Although the concurrency features of Go can make some problems easy
+to structure as parallel computations, Go is a concurrent language,
+not a parallel one, and not all parallelization problems fit Go's model.
+For a discussion of the distinction, see the talk cited in
+<a href="http://blog.golang.org/2013/01/concurrency-is-not-parallelism.html">this
+blog post</a>.
+
<h3 id="leaky_buffer">A leaky buffer</h3>
<p>
@@ -2785,7 +3226,7 @@ it is much more informative than the plain
<p>
When feasible, error strings should identify their origin, such as by having
-a prefix naming the package that generated the error. For example, in package
+a prefix naming the operation or package that generated the error. For example, in package
<code>image</code>, the string representation for a decoding error due to an
unknown format is "image: unknown format".
</p>
@@ -2813,11 +3254,8 @@ for try := 0; try &lt; 2; try++ {
</pre>
<p>
-The second <code>if</code> statement here is idiomatic Go.
-The type assertion <code>err.(*os.PathError)</code> is
-checked with the "comma ok" idiom (mentioned <a href="#maps">earlier</a>
-in the context of examining maps).
-If the type assertion fails, <code>ok</code> will be false, and <code>e</code>
+The second <code>if</code> statement here is another <a href="#interface_conversion">type assertion</a>.
+If it fails, <code>ok</code> will be false, and <code>e</code>
will be <code>nil</code>.
If it succeeds, <code>ok</code> will be true, which means the
error was of type <code>*os.PathError</code>, and then so is <code>e</code>,
@@ -2840,9 +3278,7 @@ that in effect creates a run-time error that will stop the program
(but see the next section). The function takes a single argument
of arbitrary type&mdash;often a string&mdash;to be printed as the
program dies. It's also a way to indicate that something impossible has
-happened, such as exiting an infinite loop. In fact, the compiler
-recognizes a <code>panic</code> at the end of a function and
-suppresses the usual check for a <code>return</code> statement.
+happened, such as exiting an infinite loop.
</p>
@@ -2944,7 +3380,7 @@ With our recovery pattern in place, the <code>do</code>
function (and anything it calls) can get out of any bad situation
cleanly by calling <code>panic</code>. We can use that idea to
simplify error handling in complex software. Let's look at an
-idealized excerpt from the <code>regexp</code> package, which reports
+idealized version of a <code>regexp</code> package, which reports
parsing errors by calling <code>panic</code> with a local
error type. Here's the definition of <code>Error</code>,
an <code>error</code> method, and the <code>Compile</code> function.
@@ -2980,23 +3416,32 @@ func Compile(str string) (regexp *Regexp, err error) {
<p>
If <code>doParse</code> panics, the recovery block will set the
return value to <code>nil</code>&mdash;deferred functions can modify
-named return values. It then will then check, in the assignment
+named return values. It will then check, in the assignment
to <code>err</code>, that the problem was a parse error by asserting
that it has the local type <code>Error</code>.
If it does not, the type assertion will fail, causing a run-time error
that continues the stack unwinding as though nothing had interrupted
-it. This check means that if something unexpected happens, such
+it.
+This check means that if something unexpected happens, such
as an index out of bounds, the code will fail even though we
are using <code>panic</code> and <code>recover</code> to handle
-user-triggered errors.
+parse errors.
</p>
<p>
-With error handling in place, the <code>error</code> method
+With error handling in place, the <code>error</code> method (because it's a
+method bound to a type, it's fine, even natural, for it to have the same name
+as the builtin <code>error</code> type)
makes it easy to report parse errors without worrying about unwinding
-the parse stack by hand.
+the parse stack by hand:
</p>
+<pre>
+if pos==0 {
+ re.error("'*' illegal at start of expression")
+}
+</pre>
+
<p>
Useful though this pattern is, it should be used only within a package.
<code>Parse</code> turns its internal <code>panic</code> calls into
@@ -3015,155 +3460,6 @@ filter unexpected problems and re-panic with the original error.
That's left as an exercise for the reader.
</p>
-<h2 id="blank">Blank identifier</h2>
-
-<p>
-Go defines a special identifier <code>_</code>, called the <i>blank identifier</i>.
-The blank identifier can be used in a declaration to avoid
-declaring a name, and it can be used in an assignment to discard a value.
-This definition makes it useful in a variety of contexts.
-</p>
-
-<h3 id="blank_assign">Multiple assignment</h3>
-
-<p>
-If an assignment requires multiple values on the left side,
-but one of the values will not be used by the program,
-using the blank identifier in the assignment avoids the need
-to create a dummy variable.
-We saw one example of this in the discussion of
-<a href="#for">for loops</a> above.
-</p>
-<pre>
-sum := 0
-for _, value := range array {
- sum += value
-}
-</pre>
-
-<p>
-Another common use is when calling a function that returns
-a value and an error, but only the error is important.
-</p>
-<pre>
-if _, err := os.Stat(path); os.IsNotExist(err) {
- fmt.Printf("%s does not exist\n", path)
-}
-</pre>
-
-<p>
-A final use that is more common than it should be is to
-discard the error from a function that is not expected to fail.
-This is usually a mistake: when the function does fail, the code
-will continue on and probably panic dereferencing a nil pointer.
-</p>
-<pre>
-// Always check errors: this program crashes if path does not exist.
-fi, _ := os.Stat(path)
-fmt.Printf("%s is %d bytes\n", path, fi.Size())
-</pre>
-
-<h3 id="blank_unused">Unused imports and variables</h3>
-
-<p>
-Go defines that it is an error to import a package without using it,
-or to declare a variable without using its value.
-Unused imports bloat a program and lengthen compiles unnecessarily;
-a variable that is initialized but not used is at least
-a wasted computation and perhaps indicative of a
-larger bug.
-Of course, both of these situations also arise in programs
-that are under active development, as you test and refine
-your code.
-</p>
-<p>
-For example, in this program, there are two unused imports
-(<code>fmt</code> and <code>io</code>)
-and an unused variable (<code>greeting</code>).
-</p>
-{{code "/doc/progs/unused1.go" `/package/` `$`}}
-<p>
-Top-level blank declarations referring to the packages
-will silence the unused import errors.
-By convention, these declarations should come immediately after
-the imports, as a reminder to clean things up later.
-Similarly, assigning <code>greeting</code> to a blank identifier
-will silence the unused variable error.
-</p>
-{{code "/doc/progs/unused2.go" `/package/` `$`}}
-
-<h3 id="blank_import">Import for side effect</h3>
-
-<p>
-An unused import like <code>fmt</code> or <code>io</code> in the last section
-should eventually be used or removed:
-blank assignments identify code as a work in progress.
-But sometimes it is useful to import a package only for its
-side effects, without any explicit use.
-For example, during its <code>init</code> function,
-the <code><a href="/pkg/net/http/pprof/">net/http/pprof</a></code>
-package registers HTTP handlers that provide useful
-debugging information. It has an exported API too, but
-most clients need only the handler registration.
-In this situation, it is conventional to rename the package
-to the blank identifier:
-</p>
-<pre>
-import _ "net/http/pprof"
-</pre>
-<p>
-This form of import makes clear that the package is being
-imported for its side effects, because there is no other possible
-use of the package: in this file, it doesn't have a name.
-</p>
-
-<h3 id="blank_implements">Interface checks</h3>
-
-<p>
-As we saw in the discussion of <a href="#interfaces_and_types">interfaces</a> above,
-Go does not require a type to declare explicitly that it implements an interface.
-It implements the interface by simply implementing the required methods.
-This makes Go programs more lightweight and flexible, and it can avoid
-unnecessary dependencies between packages.
-Most interface conversions are static, visible to the compiler,
-and therefore checked at compile time.
-For example, passing an <code>*os.File</code> to a function
-expecting an <code>io.Reader</code> will not compile unless
-<code>*os.File</code> implements the <code>io.Reader</code> interface.
-</p>
-<p>
-However, some types that are used only to satisfy dynamic interface checks.
-For example, the <code><a href="/pkg/encoding/json/">encoding/json</a></code>
-package defines a <code><a href="/pkg/encoding/json/#Marshaler">Marshaler</a></code>
-interface. If the JSON encoder encounters a type implementing that interface,
-the encoder will let the type convert itself to JSON instead of using the standard
-conversion.
-This check is done only at runtime, with code like:
-</p>
-<pre>
-m, ok := val.(json.Marshaler)
-</pre>
-<p>
-If a type—for example,
-<code><a href="/pkg/encoding/json/#RawMessage">json.RawMessage</a></code>—intends
-to customize its JSON representation, it should implement
-<code>json.Marshaler</code>, but there are no static conversions that would
-cause the compiler to verify this automatically.
-A declaration can be used to add such a check:
-</p>
-<pre>
-var _ json.Marshaler = (*RawMessage)(nil)
-</pre>
-<p>
-As part of type-checking this static assignment of a
-<code>*RawMessage</code> to a <code>Marshaler</code>,
-the Go compiler will require that <code>*RawMessage</code> implements <code>Marshaler</code>.
-Using the blank identifier here indicates that
-the declaration exists only for the type checking,
-not to create a variable.
-Conventionally, such declarations are used only when there are
-no static conversions already present in the code.
-</p>
<h2 id="web_server">A web server</h2>