</p>
<pre><!--{{code "progs/error.go" `/func Open/`}}
--->func Open(name string) (file *File, err error)
-</pre>
+-->func Open(name string) (file *File, err error)</pre>
<p>
The following code uses <code>os.Open</code> to open a file. If an error
</p>
<pre><!--{{code "progs/error.go" `/func openFile/` `/STOP/`}}
---> f, err := os.Open("filename.ext")
+-->f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
- // do something with the open *File f
-</pre>
+ // do something with the open *File f</pre>
<p>
You can get a lot done in Go knowing just this about the <code>error</code>
func (e *errorString) Error() string {
return e.s
-}
-</pre>
+}</pre>
<p>
You can construct one of these values with the <code>errors.New</code>
-->// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
-}
-</pre>
+}</pre>
<p>
Here's how you might use <code>errors.New</code>:
return 0, errors.New("math: square root of negative number")
}
// implementation
-}
-</pre>
+}</pre>
<p>
A caller passing a negative argument to <code>Sqrt</code> receives a non-nil
</p>
<pre><!--{{code "progs/error.go" `/func printErr/` `/STOP/`}}
---> f, err := Sqrt(-1)
+-->f, err := Sqrt(-1)
if err != nil {
fmt.Println(err)
- }
-</pre>
+ }</pre>
<p>
The <a href="/pkg/fmt/">fmt</a> package formats an <code>error</code> value
</p>
<pre><!--{{code "progs/error.go" `/fmtError/` `/STOP/`}}
---> if f < 0 {
+-->if f < 0 {
return 0, fmt.Errorf("math: square root of negative number %g", f)
- }
-</pre>
+ }</pre>
<p>
In many cases <code>fmt.Errorf</code> is good enough, but since
func (f NegativeSqrtError) Error() string {
return fmt.Sprintf("math: square root of negative number %g", float64(f))
-}
-</pre>
+}</pre>
<p>
A sophisticated caller can then use a
Offset int64 // error occurred after reading Offset bytes
}
-func (e *SyntaxError) Error() string { return e.msg }
-</pre>
+func (e *SyntaxError) Error() string { return e.msg }</pre>
<p>
The <code>Offset</code> field isn't even shown in the default formatting of the
</p>
<pre><!--{{code "progs/error.go" `/func decodeError/` `/STOP/`}}
---> if err := dec.Decode(&val); err != nil {
+-->if err := dec.Decode(&val); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf("%s:%d:%d: %v", f.Name(), line, col, err)
}
return err
- }
-</pre>
+ }</pre>
<p>
(This is a slightly simplified version of some
</p>
<pre><!--{{code "progs/error.go" `/func netError/` `/STOP/`}}
---> if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
+-->if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
- }
-</pre>
+ }</pre>
<p>
<b>Simplifying repetitive error handling</b>
if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500)
}
-}
-</pre>
+}</pre>
<p>
This function handles errors returned by the <code>datastore.Get</code>
</p>
<pre><!--{{code "progs/error3.go" `/type appHandler/`}}
--->type appHandler func(http.ResponseWriter, *http.Request) error
-</pre>
+-->type appHandler func(http.ResponseWriter, *http.Request) error</pre>
<p>
Then we can change our <code>viewRecord</code> function to return errors:
return err
}
return viewTemplate.Execute(w, record)
-}
-</pre>
+}</pre>
<p>
This is simpler than the original version, but the <a
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
}
-}
-</pre>
+}</pre>
<p>
The <code>ServeHTTP</code> method calls the <code>appHandler</code> function
<pre><!--{{code "progs/error3.go" `/func init/` `/STOP/`}}
-->func init() {
http.Handle("/view", appHandler(viewRecord))
-}
-</pre>
+}</pre>
<p>
With this basic error handling infrastructure in place, we can make it more
Error error
Message string
Code int
-}
-</pre>
+}</pre>
<p>
Next we modify the appHandler type to return <code>*appError</code> values:
</p>
<pre><!--{{code "progs/error4.go" `/type appHandler/`}}
--->type appHandler func(http.ResponseWriter, *http.Request) *appError
-</pre>
+-->type appHandler func(http.ResponseWriter, *http.Request) *appError</pre>
<p>
(It's usually a mistake to pass back the concrete type of an error rather than
c.Errorf("%v", e.Error)
http.Error(w, e.Message, e.Code)
}
-}
-</pre>
+}</pre>
<p>
Finally, we update <code>viewRecord</code> to the new function signature and
return &appError{err, "Can't display record", 500}
}
return nil
-}
-</pre>
+}</pre>
<p>
This version of <code>viewRecord</code> is the same length as the original, but
</p>
<pre><!--{{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
---> greeting := []byte{}
- greeting = append(greeting, []byte("hello ")...)
-</pre>
+-->greeting := []byte{}
+ greeting = append(greeting, []byte("hello ")...)</pre>
<p>
By analogy with the similar property of <code>copy</code>, Go 1
</p>
<pre><!--{{code "progs/go1.go" `/append.*world/`}}
---> greeting = append(greeting, "world"...)
-</pre>
+-->greeting = append(greeting, "world"...)</pre>
<p>
<em>Updating</em>:
</p>
<pre><!--{{code "progs/go1.go" `/type Date struct/` `/STOP/`}}
---> type Date struct {
+-->type Date struct {
month string
day int
}
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
- }
-</pre>
+ }</pre>
<p>
<em>Updating</em>:
c := make(chan int)
go initializationFunction(c)
PackageGlobal = <-c
-}
-</pre>
+}</pre>
<p>
<em>Updating</em>:
</p>
<pre><!--{{code "progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}}
---> 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")
- }
-</pre>
+ }</pre>
<p>
<em>Updating</em>:
</p>
<pre><!--{{code "progs/go1.go" `/delete\(m, k\)/`}}
---> delete(m, k)
-</pre>
+-->delete(m, k)</pre>
<p>
will delete the map entry retrieved by the expression <code>m[k]</code>.
</p>
<pre><!--{{code "progs/go1.go" `/Sunday/` `/^ }/`}}
---> 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)
- }
-</pre>
+ }</pre>
<p>
<em>Updating</em>:
</p>
<pre><!--{{code "progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
---> sa := []int{1, 2, 3}
+-->sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
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)
-</pre>
+ sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)</pre>
<p>
<em>Updating</em>:
</p>
<pre><!--{{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
---> type Day struct {
+-->type Day struct {
long string
short string
}
Christmas: true,
Thanksgiving: true,
}
- fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
-</pre>
+ fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])</pre>
<p>
Note that equality is still undefined for slices, for which the
func (se *SyntaxError) Error() string {
return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
-}
-</pre>
+}</pre>
<p>
All standard packages have been updated to use the new interface; the old <code>os.Error</code> is gone.
</p>
<pre><!--{{code "progs/go1.go" `/ErrSyntax/`}}
---> var ErrSyntax = errors.New("syntax error")
-</pre>
+-->var ErrSyntax = errors.New("syntax error")</pre>
<p>
<em>Updating</em>:
delta := wakeup.Sub(now) // A Duration.
log.Printf("Sleeping for %.3fs", delta.Seconds())
time.Sleep(delta)
-}
-</pre>
+}</pre>
<p>
The new types, methods, and constants have been propagated through
func main() {
fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")
-}
-</pre>
+}</pre>
<p>
Every Go source file declares, using a <code>package</code> statement, which package it's part of.
It may also import other packages to use their facilities.
s += Newline
}
os.Stdout.WriteString(s)
-}
-</pre>
+}</pre>
<p>
This program is small but it's doing a number of new things. In the last example,
we saw <code>func</code> introduce a function. The keywords <code>var</code>, <code>const</code>, and <code>type</code>
There's one in the <code>for</code> clause on the next line:
<p>
<pre><!--{{code "progs/echo.go" `/for/`}}
---> for i := 0; i < flag.NArg(); i++ {
-</pre>
+-->for i := 0; i < flag.NArg(); i++ {</pre>
<p>
The <code>flag</code> package has parsed the arguments and left the non-flag arguments
in a list that can be iterated over in the obvious way.
reassigning it. This snippet from <code>strings.go</code> is legal code:
<p>
<pre><!--{{code "progs/strings.go" `/hello/` `/ciao/`}}
---> s := "hello"
+-->s := "hello"
if s[1] != 'e' {
os.Exit(1)
}
s = "good bye"
var p *string = &s
- *p = "ciao"
-</pre>
+ *p = "ciao"</pre>
<p>
However the following statements are illegal because they would modify
a <code>string</code> value:
s += a[i]
}
return s
-}
-</pre>
+}</pre>
<p>
Note how the return type (<code>int</code>) is defined for <code>sum</code> by stating it
after the parameter list.
type File struct {
fd int // file descriptor number
name string // file name at Open time
-}
-</pre>
+}</pre>
<p>
The first few lines declare the name of the
package—<code>file</code>—and then import two packages. The <code>os</code>
return nil
}
return &File{fd, name}
-}
-</pre>
+}</pre>
<p>
This returns a pointer to a new <code>File</code> structure with the file descriptor and name
filled in. This code uses Go's notion of a ''composite literal'', analogous to
Stdin = newFile(syscall.Stdin, "/dev/stdin")
Stdout = newFile(syscall.Stdout, "/dev/stdout")
Stderr = newFile(syscall.Stderr, "/dev/stderr")
-)
-</pre>
+)</pre>
<p>
The <code>newFile</code> function was not exported because it's internal. The proper,
exported factory to use is <code>OpenFile</code> (we'll explain that name in a moment):
-->func OpenFile(name string, mode int, perm uint32) (file *File, err error) {
r, err := syscall.Open(name, mode, perm)
return newFile(r, name), err
-}
-</pre>
+}</pre>
<p>
There are a number of new things in these few lines. First, <code>OpenFile</code> returns
multiple values, a <code>File</code> and an error (more about errors in a moment).
func Open(name string) (file *File, err error) {
return OpenFile(name, O_RDONLY, 0)
-}
-</pre>
+}</pre>
<p>
<pre><!--{{code "progs/file.go" `/func.Create/` `/^}/`}}
-->func Create(name string) (file *File, err error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-</pre>
+}</pre>
<p>
Back to our main story.
Now that we can build <code>Files</code>, we can write methods for them. To declare
func (file *File) String() string {
return file.name
-}
-</pre>
+}</pre>
<p>
There is no implicit <code>this</code> and the receiver variable must be used to access
members of the structure. Methods are not declared within
fmt.Printf("can't open file; err=%s\n", err.Error())
os.Exit(1)
}
-}
-</pre>
+}</pre>
<p>
The ''<code>./</code>'' in the import of ''<code>./file</code>'' tells the compiler
to use our own package rather than
cat(f)
f.Close()
}
-}
-</pre>
+}</pre>
<p>
By now this should be easy to follow, but the <code>switch</code> statement introduces some
new features. Like a <code>for</code> loop, an <code>if</code> or <code>switch</code> can include an
-->type reader interface {
Read(b []byte) (ret int, err error)
String() string
-}
-</pre>
+}</pre>
<p>
Any type that has the two methods of <code>reader</code>—regardless of whatever
other methods the type may also have—is said to <i>implement</i> the
func (r13 *rotate13) String() string {
return r13.source.String()
}
-// end of rotate13 implementation
-</pre>
+// end of rotate13 implementation</pre>
<p>
(The <code>rot13</code> function called in <code>Read</code> is trivial and not worth reproducing here.)
<p>
To use the new feature, we define a flag:
<p>
<pre><!--{{code "progs/cat_rot13.go" `/rot13Flag/`}}
--->var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
-</pre>
+-->var rot13Flag = flag.Bool("rot13", false, "rot13 the input")</pre>
<p>
and use it from within a mostly unchanged <code>cat</code> function:
<p>
}
}
}
-}
-</pre>
+}</pre>
<p>
(We could also do the wrapping in <code>main</code> and leave <code>cat</code> mostly alone, except
for changing the type of the argument; consider that an exercise.)
data.Swap(j, j-1)
}
}
-}
-</pre>
+}</pre>
<p>
The code needs only three methods, which we wrap into sort's <code>Interface</code>:
<p>
Len() int
Less(i, j int) bool
Swap(i, j int)
-}
-</pre>
+}</pre>
<p>
We can apply <code>Sort</code> to any type that implements <code>Len</code>, <code>Less</code>, and <code>Swap</code>.
The <code>sort</code> package includes the necessary methods to allow sorting of
func (p IntSlice) Len() int { return len(p) }
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-</pre>
+func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }</pre>
<p>
Here we see methods defined for non-<code>struct</code> types. You can define methods
for any type you define and name in your package.
if !sort.IsSorted(a) {
panic("fail")
}
-}
-</pre>
+}</pre>
<p>
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:
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] }
-</pre>
+func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] }</pre>
<p>
<p>
<h2>Printing</h2>
integer and can do the right thing for you. The snippet
<p>
<pre><!--{{code "progs/print.go" 10 11}}
---> var u64 uint64 = 1<<64 - 1
- fmt.Printf("%d %d\n", u64, int64(u64))
-</pre>
+-->var u64 uint64 = 1<<64 - 1
+ fmt.Printf("%d %d\n", u64, int64(u64))</pre>
<p>
prints
<p>
appropriate style, any value, even an array or structure. The output of
<p>
<pre><!--{{code "progs/print.go" 14 20}}
---> 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)
-</pre>
+ fmt.Printf("%v %v %v\n", u64, t, a)</pre>
<p>
is
<p>
to that of the <code>Printf</code> call above.
<p>
<pre><!--{{code "progs/print.go" 21 22}}
---> fmt.Print(u64, " ", t, " ", a, "\n")
- fmt.Println(u64, t, a)
-</pre>
+-->fmt.Print(u64, " ", t, " ", a, "\n")
+ fmt.Println(u64, t, a)</pre>
<p>
If you have your own type you'd like <code>Printf</code> or <code>Print</code> to format,
just give it a <code>String</code> method that returns a string. The print
func main() {
t := &testType{77, "Sunset Strip"}
fmt.Println(t)
-}
-</pre>
+}</pre>
<p>
Since <code>*testType</code> has a <code>String</code> method, the
default formatter for that type will use it and produce the output
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
-}
-</pre>
+}</pre>
<p>
The <code>generate</code> function sends the sequence 2, 3, 4, 5, ... to its
argument channel, <code>ch</code>, using the binary communications operator <code><-</code>.
out <- i // Send 'i' to channel 'out'.
}
}
-}
-</pre>
+}</pre>
<p>
The generator and filters execute concurrently. Go has
its own model of process/threads/light-weight processes/coroutines,
go filter(ch, ch1, prime)
ch = ch1
}
-}
-</pre>
+}</pre>
<p>
The first line of <code>main</code> creates the initial channel to pass to <code>generate</code>, which it
then starts up. As each prime pops out of the channel, a new <code>filter</code>
}
}()
return ch
-}
-</pre>
+}</pre>
<p>
This version does all the setup internally. It creates the output
channel, launches a goroutine running a function literal, and
}
}()
return out
-}
-</pre>
+}</pre>
<p>
The <code>sieve</code> 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:
}
}()
return out
-}
-</pre>
+}</pre>
<p>
Now <code>main</code>'s interface to the prime sieve is a channel of primes:
<p>
for i := 0; i < 100; i++ { // Print the first hundred primes.
fmt.Println(<-primes)
}
-}
-</pre>
+}</pre>
<p>
<h2>Multiplexing</h2>
<p>
-->type request struct {
a, b int
replyc chan int
-}
-</pre>
+}</pre>
<p>
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:
func run(op binOp, req *request) {
reply := op(req.a, req.b)
req.replyc <- reply
-}
-</pre>
+}</pre>
<p>
The type declaration makes <code>binOp</code> represent a function taking two integers and
returning a third.
req := <-service
go run(op, req) // don't wait for it
}
-}
-</pre>
+}</pre>
<p>
There's a new feature in the signature of <code>server</code>: the type of the
<code>service</code> channel specifies the direction of communication.
req := make(chan *request)
go server(op, req)
return req
-}
-</pre>
+}</pre>
<p>
The returned channel is send only, even though the channel was created bidirectionally.
The read end is passed to <code>server</code>, while the send end is returned
}
}
fmt.Println("done")
-}
-</pre>
+}</pre>
<p>
One annoyance with this program is that it doesn't shut down the server cleanly; when <code>main</code> returns
there are a number of lingering goroutines blocked on communication. To solve this,
quit = make(chan bool)
go server(op, service, quit)
return service, quit
-}
-</pre>
+}</pre>
<p>
It passes the quit channel to the <code>server</code> function, which uses it like this:
<p>
return
}
}
-}
-</pre>
+}</pre>
<p>
Inside <code>server</code>, the <code>select</code> statement chooses which of the multiple communications
listed by its cases can proceed. If all are blocked, it waits until one can proceed; if
at the end of main:
<p>
<pre><!--{{code "progs/server1.go" `/adder,.quit/`}}
---> adder, quit := startServer(func(a, b int) int { return a + b })
-</pre>
+-->adder, quit := startServer(func(a, b int) int { return a + b })</pre>
...
<pre><!--{{code "progs/server1.go" `/quit....true/`}}
---> quit <- true
-</pre>
+-->quit <- true</pre>
<p>
There's a lot more to Go programming and concurrent programming in general but this
quick tour should give you some of the basics.