summaryrefslogtreecommitdiff
path: root/doc/effective_go.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/effective_go.html')
-rw-r--r--doc/effective_go.html99
1 files changed, 61 insertions, 38 deletions
diff --git a/doc/effective_go.html b/doc/effective_go.html
index f9199511a..25266d6ab 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -214,7 +214,7 @@ not be used.
One adjustment <code>godoc</code> does do is to display indented
text in a fixed-width font, suitable for program snippets.
The package comment for the
-<a href="http://golang.org/pkg/fmt/"><code>fmt</code> package</a> uses this to good effect.
+<a href="/pkg/fmt/"><code>fmt</code> package</a> uses this to good effect.
</p>
<p>
@@ -288,7 +288,7 @@ var (
</pre>
<p>
-Even for private names, grouping can also indicate relationships between items,
+Grouping can also indicate relationships between items,
such as the fact that a set of variables is protected by a mutex.
</p>
@@ -350,7 +350,7 @@ not <code>encoding_base64</code> and not <code>encodingBase64</code>.
</p>
<p>
-The importer of a package will use the name to refer to its contents.
+The importer of a package will use the name to refer to its contents,
so exported names in the package can use that fact
to avoid stutter.
(Don't use the <code>import .</code> notation, which can simplify
@@ -701,6 +701,7 @@ for _, value := range array {
<p>
The blank identifier has many uses, as described in <a href="#blank">a later section</a>.
+</p>
<p>
For strings, the <code>range</code> does more work for you, breaking out individual
@@ -709,7 +710,7 @@ Erroneous encodings consume one byte and produce the
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>
+See <a href="/ref/spec#Rune_literals">the language specification</a>
for details.)
The loop
</p>
@@ -849,7 +850,7 @@ func Compare(a, b []byte) int {
}
</pre>
-<h2 id="type_switch">Type switch</h2>
+<h3 id="type_switch">Type switch</h3>
<p>
A switch can also be used to discover the dynamic type of an interface
@@ -1385,8 +1386,9 @@ func (file *File) Read(buf []byte) (n int, err error)
</pre>
<p>
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
-<code>b</code>, <i>slice</i> (here used as a verb) the buffer.
+any.
+To read into the first 32 bytes of a larger buffer
+<code>buf</code>, <i>slice</i> (here used as a verb) the buffer.
</p>
<pre>
n, err := f.Read(buf[0:32])
@@ -1487,7 +1489,7 @@ 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:
+First, a line at a time:
</p>
<pre>
@@ -2054,10 +2056,22 @@ We pass the address of a <code>ByteSlice</code>
because only <code>*ByteSlice</code> satisfies <code>io.Writer</code>.
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
-invoked on pointers. This is because pointer methods can modify the
-receiver; invoking them on a copy of the value would cause those
-modifications to be discarded.
+invoked on pointers.
</p>
+
+<p>
+This rule arises because pointer methods can modify the receiver; invoking
+them on a value would cause the method to receive a copy of the value, so
+any modifications would be discarded.
+The language therefore disallows this mistake.
+There is a handy exception, though. When the value is addressable, the
+language takes care of the common case of invoking a pointer method on a
+value by inserting the address operator automatically.
+In our example, the variable <code>b</code> is addressable, so we can call
+its <code>Write</code> method with just <code>b.Write</code>. The compiler
+will rewrite that to <code>(&amp;b).Write</code> for us.
+</p>
+
<p>
By the way, the idea of using <code>Write</code> on a slice of bytes
is central to the implementation of <code>bytes.Buffer</code>.
@@ -2173,6 +2187,7 @@ 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:
+</p>
<pre>
value.(typeName)
@@ -2463,6 +2478,8 @@ It has uses beyond those we've seen already.
<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>
+
<p>
If an assignment requires multiple values on the left side,
but one of the values will not be used by the program,
@@ -2937,26 +2954,19 @@ 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 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.
+to <code>handle</code>, which sends a value into the channel, processes
+the request, and then receives a value from the channel
+to ready the &ldquo;semaphore&rdquo; for the next consumer.
The capacity of the channel buffer limits the number of
-simultaneous calls to <code>process</code>,
-so during initialization we prime the channel by filling it to capacity.
+simultaneous calls to <code>process</code>.
</p>
<pre>
var sem = make(chan int, MaxOutstanding)
func handle(r *Request) {
- &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 &lt; MaxOutstanding; i++ {
- sem &lt;- 1
- }
+ sem &lt;- 1 // Wait for active queue to drain.
+ process(r) // May take a long time.
+ &lt;-sem // Done; enable next request to run.
}
func Serve(queue chan *Request) {
@@ -2968,10 +2978,9 @@ 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.
+Once <code>MaxOutstanding</code> handlers are executing <code>process</code>,
+any more will block trying to send into the filled channel buffer,
+until one of the existing handlers finishes and receives from the buffer.
</p>
<p>
@@ -2988,10 +2997,10 @@ Here's an obvious solution, but beware it has a bug we'll fix subsequently:
<pre>
func Serve(queue chan *Request) {
for req := range queue {
- &lt;-sem
+ sem &lt;- 1
go func() {
process(req) // Buggy; see explanation below.
- sem &lt;- 1
+ &lt;-sem
}()
}
}</pre>
@@ -3009,10 +3018,10 @@ to the closure in the goroutine:
<pre>
func Serve(queue chan *Request) {
for req := range queue {
- &lt;-sem
+ sem &lt;- 1
go func(req *Request) {
process(req)
- sem &lt;- 1
+ &lt;-sem
}(req)
}
}</pre>
@@ -3027,11 +3036,11 @@ name, as in this example:
<pre>
func Serve(queue chan *Request) {
for req := range queue {
- &lt;-sem
req := req // Create new instance of req for the goroutine.
+ sem &lt;- 1
go func() {
process(req)
- sem &lt;- 1
+ &lt;-sem
}()
}
}</pre>
@@ -3278,9 +3287,18 @@ the garbage collector for bookkeeping.
<p>
Library routines must often return some sort of error indication to
-the caller. As mentioned earlier, Go's multivalue return makes it
+the caller.
+As mentioned earlier, Go's multivalue return makes it
easy to return a detailed error description alongside the normal
-return value. By convention, errors have type <code>error</code>,
+return value.
+It is good style to use this feature to provide detailed error information.
+For example, as we'll see, <code>os.Open</code> doesn't
+just return a <code>nil</code> pointer on failure, it also returns an
+error value that describes what went wrong.
+</p>
+
+<p>
+By convention, errors have type <code>error</code>,
a simple built-in interface.
</p>
<pre>
@@ -3292,7 +3310,12 @@ type error interface {
A library writer is free to implement this interface with a
richer model under the covers, making it possible not only
to see the error but also to provide some context.
-For example, <code>os.Open</code> returns an <code>os.PathError</code>.
+As mentioned, alongside the usual <code>*os.File</code>
+return value, <code>os.Open</code> also returns an
+error value.
+If the file is opened successfully, the error will be <code>nil</code>,
+but when there is a problem, it will hold an
+<code>os.PathError</code>:
</p>
<pre>
// PathError records an error and the operation and