http.Handler interface's
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
}
-}
-
+}
The ServeHTTP
method calls the appHandler
function
@@ -339,8 +324,7 @@ Now when registering viewRecord
with the http package we use the
func init() {
http.Handle("/view", appHandler(viewRecord))
-}
-
+}
With this basic error handling infrastructure in place, we can make it more
@@ -360,16 +344,14 @@ To do this we create an appError
struct containing an
Error error
Message string
Code int
-}
-
+}
Next we modify the appHandler type to return *appError
values:
type appHandler func(http.ResponseWriter, *http.Request) *appError
-
+-->type appHandler func(http.ResponseWriter, *http.Request) *appError
(It's usually a mistake to pass back the concrete type of an error rather than
@@ -392,8 +374,7 @@ console:
c.Errorf("%v", e.Error)
http.Error(w, e.Message, e.Code)
}
-}
-
+}
Finally, we update viewRecord
to the new function signature and
@@ -412,8 +393,7 @@ have it return more context when it encounters an error:
return &appError{err, "Can't display record", 500}
}
return nil
-}
-
+}
This version of viewRecord
is the same length as the original, but
diff --git a/doc/effective_go.html b/doc/effective_go.html
index 0e0a36bd526..43b18e6179a 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -1690,8 +1690,7 @@ const (
EB
ZB
YB
-)
-
+)
The ability to attach a method such as String
to a
type makes it possible for such values to format themselves
@@ -1718,8 +1717,7 @@ automatically for printing, even as part of a general type.
return fmt.Sprintf("%.2fKB", float64(b/KB))
}
return fmt.Sprintf("%.2fB", float64(b))
-}
-
+}
(The float64
conversions prevent Sprintf
from recurring back through the String
method for
@@ -1893,8 +1891,7 @@ func (s Sequence) String() string {
str += fmt.Sprint(elem)
}
return str + "]"
-}
-
+}
Conversions
@@ -3044,8 +3041,7 @@ value="Show QR" name=qr>
</form>
</body>
</html>
-`
-
+`
The pieces up to main
should be easy to follow.
The one flag sets a default HTTP port for our server. The template
diff --git a/doc/go1.html b/doc/go1.html
index f362fe970a6..dbf263e0821 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -44,9 +44,8 @@ call.
greeting := []byte{}
- greeting = append(greeting, []byte("hello ")...)
-
+-->greeting := []byte{}
+ greeting = append(greeting, []byte("hello ")...)
By analogy with the similar property of copy
, Go 1
@@ -55,8 +54,7 @@ slice; the conversion is no longer necessary:
greeting = append(greeting, "world"...)
-
+-->greeting = append(greeting, "world"...)
Updating:
@@ -97,7 +95,7 @@ All four of the initializations in this example are legal; the last one was ille
type Date struct {
+-->type Date struct {
month string
day int
}
@@ -124,8 +122,7 @@ All four of the initializations in this example are legal; the last one was ille
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
- }
-
+ }
Updating:
@@ -152,8 +149,7 @@ func init() {
c := make(chan int)
go initializationFunction(c)
PackageGlobal = <-c
-}
-
+}
Updating:
@@ -186,14 +182,13 @@ relatives now take and return a rune
.
delta := 'δ' // delta has type rune.
+-->delta := 'δ' // delta has type rune.
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != 'δ'+1 {
log.Fatal("inconsistent casing for Greek")
- }
-
+ }
Updating:
@@ -236,8 +231,7 @@ function, delete
. The call
delete(m, k)
-
+-->delete(m, k)
will delete the map entry retrieved by the expression m[k]
.
@@ -264,12 +258,11 @@ Code should not assume that the elements are visited in any particular order.
m := map[string]int{"Sunday": 0, "Monday": 1}
+-->m := map[string]int{"Sunday": 0, "Monday": 1}
for name, value := range m {
// This loop should not assume Sunday will be visited first.
f(name, value)
- }
-
+ }
Updating:
@@ -299,7 +292,7 @@ These examples illustrate the behavior.
sa := []int{1, 2, 3}
+-->sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
@@ -308,8 +301,7 @@ These examples illustrate the behavior.
sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
sc := []int{1, 2, 3}
- sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
-
+ sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
Updating:
@@ -417,7 +409,7 @@ As a result, structs and arrays can now be used as map keys:
type Day struct {
+-->type Day struct {
long string
short string
}
@@ -427,8 +419,7 @@ As a result, structs and arrays can now be used as map keys:
Christmas: true,
Thanksgiving: true,
}
- fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
-
+ fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
Note that equality is still undefined for slices, for which the
@@ -575,8 +566,7 @@ does for String
, for easy printing of error values.
func (se *SyntaxError) Error() string {
return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
-}
-
+}
All standard packages have been updated to use the new interface; the old os.Error
is gone.
@@ -595,8 +585,7 @@ to turn a string into an error. It replaces the old os.NewError
.
var ErrSyntax = errors.New("syntax error")
-
+-->var ErrSyntax = errors.New("syntax error")
Updating:
@@ -677,8 +666,7 @@ func sleepUntil(wakeup time.Time) {
delta := wakeup.Sub(now) // A Duration.
log.Printf("Sleeping for %.3fs", delta.Seconds())
time.Sleep(delta)
-}
-
+}
The new types, methods, and constants have been propagated through
diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html
index d97ebe8ba4f..13c352b87cd 100644
--- a/doc/go_tutorial.html
+++ b/doc/go_tutorial.html
@@ -33,8 +33,7 @@ import fmt "fmt" // Package implementing formatted I/O.
func main() {
fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")
-}
-
+}
Every Go source file declares, using a package
statement, which package it's part of.
It may also import other packages to use their facilities.
@@ -144,8 +143,7 @@ func main() {
s += Newline
}
os.Stdout.WriteString(s)
-}
-
+}
This program is small but it's doing a number of new things. In the last example,
we saw func
introduce a function. The keywords var
, const
, and type
@@ -211,8 +209,7 @@ The :=
operator is used a lot in Go to represent an initializing de
There's one in the for
clause on the next line:
for i := 0; i < flag.NArg(); i++ {
-
+-->for i := 0; i < flag.NArg(); i++ {
The flag
package has parsed the arguments and left the non-flag arguments
in a list that can be iterated over in the obvious way.
@@ -261,14 +258,13 @@ of course you can change a string variable simply by
reassigning it. This snippet from strings.go
is legal code:
s := "hello"
+-->s := "hello"
if s[1] != 'e' {
os.Exit(1)
}
s = "good bye"
var p *string = &s
- *p = "ciao"
-
+ *p = "ciao"
However the following statements are illegal because they would modify
a string
value:
@@ -340,8 +336,7 @@ Using slices one can write this function (from sum.go
):
s += a[i]
}
return s
-}
-
+}
Note how the return type (int
) is defined for sum
by stating it
after the parameter list.
@@ -493,8 +488,7 @@ import (
type File struct {
fd int // file descriptor number
name string // file name at Open time
-}
-
+}
The first few lines declare the name of the
package—file
—and then import two packages. The os
@@ -535,8 +529,7 @@ First, though, here is a factory to create a File
:
return nil
}
return &File{fd, name}
-}
-
+}
This returns a pointer to a new File
structure with the file descriptor and name
filled in. This code uses Go's notion of a ''composite literal'', analogous to
@@ -560,8 +553,7 @@ We can use the factory to construct some familiar, exported variables of type
+)
The newFile
function was not exported because it's internal. The proper,
exported factory to use is OpenFile
(we'll explain that name in a moment):
@@ -570,8 +562,7 @@ exported factory to use is OpenFile
(we'll explain that name in a m
-->func OpenFile(name string, mode int, perm uint32) (file *File, err error) {
r, err := syscall.Open(name, mode, perm)
return newFile(r, name), err
-}
-
+}
There are a number of new things in these few lines. First, OpenFile
returns
multiple values, a File
and an error (more about errors in a moment).
@@ -613,14 +604,12 @@ the tricky standard arguments to open and, especially, to create a file:
func Open(name string) (file *File, err error) {
return OpenFile(name, O_RDONLY, 0)
-}
-
+}
func Create(name string) (file *File, err error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
+}
Back to our main story.
Now that we can build Files
, we can write methods for them. To declare
@@ -657,8 +646,7 @@ func (file *File) Write(b []byte) (ret int, err error) {
func (file *File) String() string {
return file.name
-}
-
+}
There is no implicit this
and the receiver variable must be used to access
members of the structure. Methods are not declared within
@@ -692,8 +680,7 @@ func main() {
fmt.Printf("can't open file; err=%s\n", err.Error())
os.Exit(1)
}
-}
-
+}
The ''./
'' in the import of ''./file
'' tells the compiler
to use our own package rather than
@@ -761,8 +748,7 @@ func main() {
cat(f)
f.Close()
}
-}
-
+}
By now this should be easy to follow, but the switch
statement introduces some
new features. Like a for
loop, an if
or switch
can include an
@@ -794,8 +780,7 @@ Here is code from progs/cat_rot13.go
:
-->type reader interface {
Read(b []byte) (ret int, err error)
String() string
-}
-
+}
Any type that has the two methods of reader
—regardless of whatever
other methods the type may also have—is said to implement the
@@ -827,16 +812,14 @@ func (r13 *rotate13) Read(b []byte) (ret int, err error) {
func (r13 *rotate13) String() string {
return r13.source.String()
}
-// end of rotate13 implementation
-
+// end of rotate13 implementation
(The rot13
function called in Read
is trivial and not worth reproducing here.)
To use the new feature, we define a flag:
var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
-
+-->var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
and use it from within a mostly unchanged cat
function:
@@ -863,8 +846,7 @@ and use it from within a mostly unchanged cat
function:
}
}
}
-}
-
+}
(We could also do the wrapping in main
and leave cat
mostly alone, except
for changing the type of the argument; consider that an exercise.)
@@ -918,8 +900,7 @@ As an example, consider this simple sort algorithm taken from progs/sort.g
data.Swap(j, j-1)
}
}
-}
-
+}
The code needs only three methods, which we wrap into sort's Interface
:
@@ -928,8 +909,7 @@ The code needs only three methods, which we wrap into sort's Interface
+}
We can apply Sort
to any type that implements Len
, Less
, and Swap
.
The sort
package includes the necessary methods to allow sorting of
@@ -940,8 +920,7 @@ arrays of integers, strings, etc.; here's the code for arrays of int
+func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
Here we see methods defined for non-struct
types. You can define methods
for any type you define and name in your package.
@@ -958,8 +937,7 @@ to test that the result is sorted.
if !sort.IsSorted(a) {
panic("fail")
}
-}
-
+}
If we have a new type we want to be able to sort, all we need to do is
to implement the three methods for that type, like this:
@@ -977,8 +955,7 @@ type dayArray struct {
func (p *dayArray) Len() int { return len(p.data) }
func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num }
-func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] }
-
+func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] }
Printing
@@ -1013,9 +990,8 @@ can just say %d
; Printf
knows the size and signedness
integer and can do the right thing for you. The snippet
var u64 uint64 = 1<<64 - 1
- fmt.Printf("%d %d\n", u64, int64(u64))
-
+-->var u64 uint64 = 1<<64 - 1
+ fmt.Printf("%d %d\n", u64, int64(u64))
prints
@@ -1027,14 +1003,13 @@ In fact, if you're lazy the format %v
will print, in a simple
appropriate style, any value, even an array or structure. The output of
type T struct {
+-->type T struct {
a int
b string
}
t := T{77, "Sunset Strip"}
a := []int{1, 2, 3, 4}
- fmt.Printf("%v %v %v\n", u64, t, a)
-
+ fmt.Printf("%v %v %v\n", u64, t, a)
is
@@ -1050,9 +1025,8 @@ and adds a newline. The output of each of these two lines is identical
to that of the Printf
call above.
fmt.Print(u64, " ", t, " ", a, "\n")
- fmt.Println(u64, t, a)
-
+-->fmt.Print(u64, " ", t, " ", a, "\n")
+ fmt.Println(u64, t, a)
If you have your own type you'd like Printf
or Print
to format,
just give it a String
method that returns a string. The print
@@ -1073,8 +1047,7 @@ func (t *testType) String() string {
func main() {
t := &testType{77, "Sunset Strip"}
fmt.Println(t)
-}
-
+}
Since *testType
has a String
method, the
default formatter for that type will use it and produce the output
@@ -1200,8 +1173,7 @@ func generate(ch chan int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
-}
-
+}
The generate
function sends the sequence 2, 3, 4, 5, ... to its
argument channel, ch
, using the binary communications operator <-
.
@@ -1223,8 +1195,7 @@ func filter(in, out chan int, prime int) {
out <- i // Send 'i' to channel 'out'.
}
}
-}
-
+}
The generator and filters execute concurrently. Go has
its own model of process/threads/light-weight processes/coroutines,
@@ -1262,8 +1233,7 @@ together:
go filter(ch, ch1, prime)
ch = ch1
}
-}
-
+}
The first line of main
creates the initial channel to pass to generate
, which it
then starts up. As each prime pops out of the channel, a new filter
@@ -1283,8 +1253,7 @@ of generate
, from progs/sieve1.go
:
}
}()
return ch
-}
-
+}
This version does all the setup internally. It creates the output
channel, launches a goroutine running a function literal, and
@@ -1309,8 +1278,7 @@ The same change can be made to filter
:
}
}()
return out
-}
-
+}
The sieve
function's main loop becomes simpler and clearer as a
result, and while we're at it let's turn it into a factory too:
@@ -1327,8 +1295,7 @@ result, and while we're at it let's turn it into a factory too:
}
}()
return out
-}
-
+}
Now main
's interface to the prime sieve is a channel of primes:
@@ -1338,8 +1305,7 @@ Now main
's interface to the prime sieve is a channel of primes:
for i := 0; i < 100; i++ { // Print the first hundred primes.
fmt.Println(<-primes)
}
-}
-
+}
Multiplexing
@@ -1354,8 +1320,7 @@ that will be used for the reply.
-->type request struct {
a, b int
replyc chan int
-}
-
+}
The server will be trivial: it will do simple binary operations on integers. Here's the
code that invokes the operation and responds to the request:
@@ -1366,8 +1331,7 @@ code that invokes the operation and responds to the request:
func run(op binOp, req *request) {
reply := op(req.a, req.b)
req.replyc <- reply
-}
-
+}
The type declaration makes binOp
represent a function taking two integers and
returning a third.
@@ -1381,8 +1345,7 @@ a long-running operation, starting a goroutine to do the actual work.
req := <-service
go run(op, req) // don't wait for it
}
-}
-
+}
There's a new feature in the signature of server
: the type of the
service
channel specifies the direction of communication.
@@ -1403,8 +1366,7 @@ connected to it:
req := make(chan *request)
go server(op, req)
return req
-}
-
+}
The returned channel is send only, even though the channel was created bidirectionally.
The read end is passed to server
, while the send end is returned
@@ -1441,8 +1403,7 @@ does it check the results.
}
}
fmt.Println("done")
-}
-
+}
One annoyance with this program is that it doesn't shut down the server cleanly; when main
returns
there are a number of lingering goroutines blocked on communication. To solve this,
@@ -1454,8 +1415,7 @@ we can provide a second, quit
channel to the server:
quit = make(chan bool)
go server(op, service, quit)
return service, quit
-}
-
+}
It passes the quit channel to the server
function, which uses it like this:
@@ -1469,8 +1429,7 @@ It passes the quit channel to the server
function, which uses it li
return
}
}
-}
-
+}
Inside server
, the select
statement chooses which of the multiple communications
listed by its cases can proceed. If all are blocked, it waits until one can proceed; if
@@ -1483,12 +1442,10 @@ All that's left is to strobe the quit
channel
at the end of main:
adder, quit := startServer(func(a, b int) int { return a + b })
-
+-->adder, quit := startServer(func(a, b int) int { return a + b })
...
quit <- true
-
+-->quit <- true
There's a lot more to Go programming and concurrent programming in general but this
quick tour should give you some of the basics.
diff --git a/doc/tmpltohtml.go b/doc/tmpltohtml.go
index df761fa421a..dbd27ab685b 100644
--- a/doc/tmpltohtml.go
+++ b/doc/tmpltohtml.go
@@ -113,6 +113,8 @@ func code(file string, arg ...interface{}) (string, error) {
default:
return "", fmt.Errorf("incorrect code invocation: code %q %q", file, arg)
}
+ // Trim spaces from output.
+ text = strings.TrimSpace(text)
// Replace tabs by spaces, which work better in HTML.
text = strings.Replace(text, "\t", " ", -1)
// Escape the program text for HTML.