1
0
mirror of https://github.com/golang/go synced 2024-11-25 14:07:56 -07:00

effective go: tiny fixes

one real bug: *[]float -> *[3]float

R=r
http://go/go-review/1024016
This commit is contained in:
Russ Cox 2009-11-08 01:07:53 -08:00
parent a011480ff3
commit 24ce19c71d

View File

@ -6,7 +6,7 @@
Go is a new language. Although it borrows ideas from Go is a new language. Although it borrows ideas from
existing languages, existing languages,
it has unusual properties that make effective Go programs it has unusual properties that make effective Go programs
different in character from programs in its relatives. different in character from programs written in its relatives.
A straightforward translation of a C++ or Java program into Go A straightforward translation of a C++ or Java program into Go
is unlikely to produce a satisfactory result—Java programs is unlikely to produce a satisfactory result—Java programs
are written in Java, not Go. are written in Java, not Go.
@ -37,7 +37,7 @@ are intended to serve not
only as the core library but also as examples of how to only as the core library but also as examples of how to
use the language. use the language.
If you have a question about how to approach a problem or how something If you have a question about how to approach a problem or how something
might be implemented they can provide answers, ideas and might be implemented, they can provide answers, ideas and
background. background.
</p> </p>
@ -83,7 +83,7 @@ type T struct {
</pre> </pre>
<p> <p>
<code>gofmt</code> will make the columns line up. <code>gofmt</code> will line up the columns:
</p> </p>
<pre> <pre>
@ -237,7 +237,7 @@ var (
<p> <p>
Even for private names, grouping can also indicate relationships between items, Even for private names, grouping can also indicate relationships between items,
such as the fact that a set of variables is controlled by a mutex. such as the fact that a set of variables is protected by a mutex.
</p> </p>
<pre> <pre>
@ -293,14 +293,14 @@ defines which version is being used.
Another convention is that the package name is the base name of Another convention is that the package name is the base name of
its source directory; its source directory;
the package in <code>src/pkg/container/vector</code> the package in <code>src/pkg/container/vector</code>
is installed as <code>"container/vector"</code> but has name <code>vector</code>, is imported as <code>"container/vector"</code> but has name <code>vector</code>,
not <code>container_vector</code> and not <code>containerVector</code>. not <code>container_vector</code> and not <code>containerVector</code>.
</p> </p>
<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
(the <code>import .</code> notation is intended mostly for tests and other (the <code>import .</code> notation is intended mostly for tests and other
unusual situations) and exported names in the package can use that fact unusual situations), so exported names in the package can use that fact
to avoid stutter. to avoid stutter.
For instance, the buffered reader type in the <code>bufio</code> package is called <code>Reader</code>, For instance, the buffered reader type in the <code>bufio</code> package is called <code>Reader</code>,
not <code>BufReader</code>, because users see it as <code>bufio.Reader</code>, not <code>BufReader</code>, because users see it as <code>bufio.Reader</code>,
@ -308,9 +308,9 @@ which is a clear, concise name.
Moreover, Moreover,
because imported entities are always addressed with their package name, <code>bufio.Reader</code> because imported entities are always addressed with their package name, <code>bufio.Reader</code>
does not conflict with <code>io.Reader</code>. does not conflict with <code>io.Reader</code>.
Similarly, the function to make new instances of <code>vector.Vector</code> Similarly, the function to make new instances of <code>vector.Vector</code>&mdash;which
&mdash;which is the definition of a <em>constructor</em> in Go&mdash;would is the definition of a <em>constructor</em> in Go&mdash;would
normally be called <code>NewVector</code> but since normally be called <code>NewVector</code>, but since
<code>Vector</code> is the only type exported by the package, and since the <code>Vector</code> is the only type exported by the package, and since the
package is called <code>vector</code>, it's called just <code>New</code>. package is called <code>vector</code>, it's called just <code>New</code>.
Clients of the package see that as <code>vector.New</code>. Clients of the package see that as <code>vector.New</code>.
@ -664,11 +664,11 @@ and modifying an argument.
</p> </p>
<p> <p>
In C, a write error is signaled by a negative byte count with the In C, a write error is signaled by a negative count with the
error code secreted away in a volatile location. error code secreted away in a volatile location.
In Go, <code>Write</code> In Go, <code>Write</code>
can return a byte count <i>and</i> an error: "Yes, you wrote some 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". 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 <code>*File.Write</code> in package <code>os</code> is:
</p> </p>
@ -765,7 +765,7 @@ They do different things and apply to different types, which can be confusing,
but the rules are simple. but the rules are simple.
Let's talk about <code>new()</code> first. Let's talk about <code>new()</code> first.
It's a built-in function essentially the same as its namesakes It's a built-in function essentially the same as its namesakes
in other languages: it allocates zeroed storage for a new item of type in other languages: <code>new(T)</code> allocates zeroed storage for a new item of type
<code>T</code> and returns its address, a value of type <code>*T</code>. <code>T</code> and returns its address, a value of type <code>*T</code>.
In Go terminology, it returns a pointer to a newly allocated zero value of type In Go terminology, it returns a pointer to a newly allocated zero value of type
<code>T</code>. <code>T</code>.
@ -873,18 +873,13 @@ order, with the missing ones left as their respective zero values. Thus we coul
<p> <p>
As a limiting case, if a composite literal contains no fields at all, it creates As 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. The expressions <code>new(File)</code> and <code>&amp;File{}</code> are equivalent.
</p> </p>
<pre>
new(File)
&amp;File{}
</pre>
<p> <p>
Composite literals can also be created for arrays, slices, and maps, Composite literals can also be created for arrays, slices, and maps,
with the field labels being indices or map keys as appropriate. with the field labels being indices or map keys as appropriate.
In these examples, the initializations work regardless of the values of <code>EnoError</code>, In these examples, the initializations work regardless of the values of <code>Enone</code>,
<code>Eio</code>, and <code>Einval</code>, as long as they are distinct. <code>Eio</code>, and <code>Einval</code>, as long as they are distinct.
</p> </p>
@ -945,7 +940,8 @@ v := make([]int, 100);
</pre> </pre>
<p> <p>
Remember that <code>make()</code> applies only to maps, slices and channels. 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>.
</p> </p>
@ -953,7 +949,7 @@ To obtain an explicit pointer allocate with <code>new()</code>.
<p> <p>
Arrays are useful when planning the detailed layout of memory and sometimes Arrays are useful when planning the detailed layout of memory and sometimes
can help avoid allocation but primarily can help avoid allocation, but primarily
they are a building block for slices, the subject of the next section. they are a building block for slices, the subject of the next section.
To lay the foundation for that topic, here are a few words about arrays. To lay the foundation for that topic, here are a few words about arrays.
</p> </p>
@ -981,7 +977,7 @@ you can pass a pointer to the array.
</p> </p>
<pre> <pre>
func Sum(a *[]float) (sum float) { func Sum(a *[3]float) (sum float) {
for _, v := range a { for _, v := range a {
sum += v sum += v
} }
@ -1010,8 +1006,8 @@ slice to another, both refer to the same underlying array. For
instance, if a function takes a slice argument, changes it makes to instance, if a function takes a slice argument, changes it makes to
the elements of the slice will be visible to the caller, analogous 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> passing a pointer to the underlying array. A <code>Read</code>
function can therefore accept a slice argument rather than a (pointer function can therefore accept a slice argument rather than a pointer
to an) array and a count; the length within the slice sets an upper and a count; the length within the slice sets an upper
limit of how much data to read. Here is the signature of the limit of how much data to read. Here is the signature of the
<code>Read</code> method of the <code>File</code> type in package <code>Read</code> method of the <code>File</code> type in package
<code>os</code>: <code>os</code>:
@ -1085,10 +1081,11 @@ structure holding the pointer, length, and capacity) is passed by value.
<p> <p>
Maps are a convenient and powerful built-in data structure to associate Maps are a convenient and powerful built-in data structure to associate
values of different types. values of different types.
The key can be of any type that implements equality, such as integers, The key can be of any type for which the equality operator is defined,
such as integers,
floats, strings, pointers, and interfaces (as long as the dynamic type floats, strings, pointers, and interfaces (as long as the dynamic type
supports equality), but not structs, arrays or slices supports equality). Structs, arrays and slices cannot be used as map keys,
because those types do not have equality defined for them. because equality is not defined on those types.
Like slices, maps are a reference type. If you pass a map to a function Like slices, maps are a reference type. If you pass a map to a function
that changes the contents of the map, the changes will be visible that changes the contents of the map, the changes will be visible
in the caller. in the caller.
@ -1514,7 +1511,7 @@ A type can implement multiple interfaces.
For instance, a collection can be sorted For instance, a collection can be sorted
by the routines in package <code>sort</code> if it implements by the routines in package <code>sort</code> if it implements
<code>sort.Interface</code>, which contains <code>Len()</code>, <code>sort.Interface</code>, which contains <code>Len()</code>,
<code>Less(i, j int)</code>, and <code>Swap(i, j int)</code>, <code>Less(i, j int) bool</code>, and <code>Swap(i, j int)</code>,
and it could also have a custom formatter. and it could also have a custom formatter.
In this contrived example <code>Sequence</code> satisfies both. In this contrived example <code>Sequence</code> satisfies both.
</p> </p>
@ -1654,7 +1651,7 @@ implementation of the <code>Cipher</code> interface and any
<code>io.Reader</code>. Because they return <code>io.Reader</code> <code>io.Reader</code>. Because they return <code>io.Reader</code>
interface values, replacing ECB interface values, replacing ECB
encryption with CBC encryption is a localized change. The constructor encryption with CBC encryption is a localized change. The constructor
calls must be edited, but because the code must treat the result only calls must be edited, but because the surrounding code must treat the result only
as an <code>io.Reader</code>, it won't notice the difference. as an <code>io.Reader</code>, it won't notice the difference.
</p> </p>
@ -2247,16 +2244,16 @@ Once the message buffer is ready, it's sent to the server on
<code>serverChan</code>. <code>serverChan</code>.
</p> </p>
<pre> <pre>
var freelist = make(chan *Buffer, 100) var freeList = make(chan *Buffer, 100)
var server_chan = make(chan *Buffer) var serverChan = make(chan *Buffer)
func client() { func client() {
for { for {
b, ok := <-freeList; // grab one if available b, ok := <-freeList; // grab a buffer if available
if !ok { // free list empty; allocate a new buffer if !ok { // if not, allocate a new one
b = new(Buffer) b = new(Buffer)
} }
load(b); // grab the next message, perhaps from the net load(b); // read next message from the net
serverChan <- b; // send to server serverChan <- b; // send to server
} }
} }
@ -2393,7 +2390,7 @@ import (
"template"; "template";
) )
var addr = flag.String("addr", ":1718", "http service address") // Q = 17, R = 18 var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18
var fmap = template.FormatterMap{ var fmap = template.FormatterMap{
"html": template.HtmlFormatter, "html": template.HtmlFormatter,
"url+html": UrlHtmlFormatter, "url+html": UrlHtmlFormatter,
@ -2456,7 +2453,7 @@ server; it blocks while the server runs.
</p> </p>
<p> <p>
<code>QR</code> just receives the request, which contains form data, and <code>QR</code> just receives the request, which contains form data, and
executes the template on the data in the field named <code>s</code>. executes the template on the data in the form value named <code>s</code>.
</p> </p>
<p> <p>
The template package, inspired by <a The template package, inspired by <a
@ -2465,12 +2462,12 @@ powerful;
this program just touches on its capabilities. this program just touches on its capabilities.
In essence, it rewrites a piece of text on the fly by substituting elements derived In essence, it rewrites a piece of text on the fly by substituting elements derived
from data items passed to <code>templ.Execute</code>, in this case the from data items passed to <code>templ.Execute</code>, in this case the
string in the form data. form value.
Within the template text (<code>templateStr</code>), Within the template text (<code>templateStr</code>),
brace-delimited pieces denote template actions. brace-delimited pieces denote template actions.
The piece from the <code>{.section @}</code> The piece from the <code>{.section @}</code>
to <code>{.end}</code> executes with the value of the data item <code>@</code>, to <code>{.end}</code> executes with the value of the data item <code>@</code>,
which is a shorthand for &ldquo;the current item&rdquo;, in this case the form data. which is a shorthand for &ldquo;the current item&rdquo;, which is the form value.
(When the string is empty, this piece of the template is suppressed.) (When the string is empty, this piece of the template is suppressed.)
</p> </p>
<p> <p>