Rob Pike
----
-(March 17, 2009)
+(March 18, 2009)
This document is a tutorial introduction to the basics of the Go systems programming
Every Go source file declares, using a "package" statement, which package it's part of.
The "main" package's "main" function is where the program starts running (after
-any initialization).
+any initialization). It may also import other packages to use their facilities.
+This program imports the package "fmt" to gain access to
+our old, now capitalized and package-qualified friend, "fmt.Printf".
Function declarations are introduced with the "func" keyword.
Go is defined to accept UTF-8 input. Strings are arrays of bytes, usually used
to store Unicode strings represented in UTF-8.
-The built-in function "print()" has been used during the early stages of
-development of the language but is not guaranteed to last. Here's a version of the
-program that doesn't depend on "print()":
-
---PROG progs/helloworld2.go
-
-This version imports the ''os'' package to acess its "Stdout" variable, of type
-"*os.File". The "import" statement is a declaration: it names the identifier ("os")
-that will be used to access members of the package imported from the file ("os"),
-found in the current directory or in a standard location.
-Given "os.Stdout" we can use its "WriteString" method to print the string.
-
The comment convention is the same as in C++:
/* ... */
top-level declaration, even though they are needed as separators <i>within</i>
a parenthesized list of declarations.
-Also notice that we've dropped the explicit name from the imports; by default,
+This program imports the ""os"" package to access its "Stdout" variable, of type
+"*os.File". The "import" statement is actually a declaration: in its general form,
+as used in our ``hello world'' program,
+it names the identifier ("fmt")
+that will be used to access members of the package imported from the file (""fmt""),
+found in the current directory or in a standard location.
+In this program, though, we've dropped the explicit name from the imports; by default,
packages are imported using the name defined by the imported package,
-which by convention is of course the file name itself. You can specify your
+which by convention is of course the file name itself. Our ``hello world'' program
+could have said just "import "fmt"".
+
+You can specify your
own import names if you want but it's only necessary if you need to resolve
a naming conflict.
+Given "os.Stdout" we can use its "WriteString" method to print the string.
+
Having imported the "flag" package, line 8 creates a global variable to hold
the value of echo's "-n" flag. The variable "n_flag" has type "*bool", pointer
to "bool".
--PROG progs/helloworld3.go
-and run the program:
+And now we can run the program:
% helloworld3
hello, world
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
-initialization statement. The "switch" on line 12 uses one to create variables
-"nr" and "er" to hold the return values from "f.Read()". (The "if" on line 19
+initialization statement. The "switch" on line 14 uses one to create variables
+"nr" and "er" to hold the return values from "f.Read()". (The "if" on line 21
has the same idea.) The "switch" statement is general: it evaluates the cases
from top to bottom looking for the first case that matches the value; the
case expressions don't need to be constants or even integers, as long as
is a form of "if-else" chain. While we're here, it should be mentioned that in
"switch" statements each "case" has an implicit "break".
-Line 19 calls "Write()" by slicing the incoming buffer, which is itself a slice.
+Line 21 calls "Write()" by slicing the incoming buffer, which is itself a slice.
Slices provide the standard Go way to handle I/O buffers.
Now let's make a variant of "cat" that optionally does "rot13" on its input.
--PROG progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/
-(The "rot13" function called on line 37 is trivial and not worth reproducing.)
+(The "rot13" function called on line 38 is trivial and not worth reproducing.)
To use the new feature, we define a flag:
(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.)
-Lines 51 through 53 set it all up: If the "rot13" flag is true, wrap the "reader"
+Lines 52 through 55 set it all up: If the "rot13" flag is true, wrap the "reader"
we received into a "rotate13" and proceed. Note that the interface variables
are values, not pointers: the argument is of type "reader", not "*reader",
even though under the covers it holds a pointer to a "struct".
The examples of formatted printing so far have been modest. In this section
we'll talk about how formatted I/O can be done well in Go.
-There's a package "fmt" that implements a version of "Printf" (upper case)
-that should look familiar:
-
---PROG progs/printf.go
-
+We've seen simple uses of the package "fmt", which
+implements "Printf", "Fprintf", and so on.
Within the "fmt" package, "Printf" is declared with this signature:
Printf(format string, v ...) (n int, errno *os.Error)
--PROG progs/sieve.go /func.main/ /^}/
-Line 23 creates the initial channel to pass to "generate", which it
+Line 25 creates the initial channel to pass to "generate", which it
then starts up. As each prime pops out of the channel, a new "filter"
is added to the pipeline and <i>its</i> output becomes the new value
of "ch".
returns the channel to the caller. It is a factory for concurrent
execution, starting the goroutine and returning its connection.
-The function literal notation (lines 6-10) allows us to construct an
+The function literal notation (lines 8-12) allows us to construct an
anonymous function and invoke it on the spot.
The same change can be made to "filter":
--PROG progs/server.go /type.binOp/ /^}/
-Line 8 defines the name "binOp" to be a function taking two integers and
+Line 10 defines the name "binOp" to be a function taking two integers and
returning a third.
The "server" routine loops forever, receiving requests and, to avoid blocking due to