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:
parent
a011480ff3
commit
24ce19c71d
@ -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>—which
|
||||||
—which is the definition of a <em>constructor</em> in Go—would
|
is the definition of a <em>constructor</em> in Go—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: “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”.
|
||||||
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>&File{}</code> are equivalent.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
|
||||||
new(File)
|
|
||||||
&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 “the current item”, in this case the form data.
|
which is a shorthand for “the current item”, 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>
|
||||||
|
Loading…
Reference in New Issue
Block a user