From 3e45412327a2654a77944249962b3652e6142299 Mon Sep 17 00:00:00 2001 From: Ondřej Surý Date: Mon, 17 Jan 2011 12:40:45 +0100 Subject: Imported Upstream version 2011.01.12 --- doc/go_tutorial.html | 109 ++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'doc/go_tutorial.html') diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html index 7eb09b5b4..11e9b4ad7 100644 --- a/doc/go_tutorial.html +++ b/doc/go_tutorial.html @@ -286,14 +286,15 @@ In Go, since arrays are values, it's meaningful (and useful) to talk about pointers to arrays.

The size of the array is part of its type; however, one can declare -a slice variable, to which one can assign a pointer to -any array -with the same element type or—much more commonly—a slice -expression of the form a[low : high], representing -the subarray indexed by low through high-1. -Slices look a lot like arrays but have +a slice variable to hold a reference to any array, of any size, +with the same element type. +A slice +expression has the form a[low : high], representing +the internal array indexed from low through high-1; the resulting +slice is indexed from 0 through high-low-1. +In short, slices look a lot like arrays but with no explicit size ([] vs. [10]) and they reference a segment of -an underlying, often anonymous, regular array. Multiple slices +an underlying, usually anonymous, regular array. Multiple slices can share data if they represent pieces of the same array; multiple arrays can never share data.

@@ -302,17 +303,28 @@ regular arrays; they're more flexible, have reference semantics, and are efficient. What they lack is the precise control of storage layout of a regular array; if you want to have a hundred elements of an array stored within your structure, you should use a regular -array. +array. To create one, use a compound value constructor—an +expression formed +from a type followed by a brace-bounded expression like this: +

+

+    [3]int{1,2,3}
+
+

+In this case the constructor builds an array of 3 ints.

When passing an array to a function, you almost always want to declare the formal parameter to be a slice. When you call -the function, take the address of the array and Go will -create (efficiently) a slice reference and pass that. +the function, slice the array to create +(efficiently) a slice reference and pass that. +By default, the lower and upper bounds of a slice match the +ends of the existing object, so the concise notation [:] +will slice the whole array.

Using slices one can write this function (from sum.go):

 
-09    func sum(a []int) int {   // returns an int
+09    func sum(a []int) int { // returns an int
 10        s := 0
 11        for i := 0; i < len(a); i++ {
 12            s += a[i]
@@ -321,32 +333,27 @@ Using slices one can write this function (from sum.go):
 15    }
 

-and invoke it like this: -

-

 
-19        s := sum(&[3]int{1,2,3})  // a slice of the array is passed to sum
-
-

Note how the return type (int) is defined for sum() by stating it after the parameter list. -The expression [3]int{1,2,3}—a type followed by a -brace-bounded -expression—is a constructor for a value, in this case an array -of 3 ints. -Putting an & -in front gives us the address of a unique instance of the value. We pass the -pointer to sum() by (implicitly) promoting it to a slice. +

+To call the function, we slice the array. This intricate call (we'll show +a simpler way in a moment) constructs +an array and slices it: +

+

+    s := sum([3]int{1,2,3}[:])
+

If you are creating a regular array but want the compiler to count the elements for you, use ... as the array size:

-    s := sum(&[...]int{1,2,3})
+    s := sum([...]int{1,2,3}[:])
 

-In practice, though, unless you're meticulous about storage layout within a -data structure, a slice itself—using empty brackets and no -&—is all you need: +That's fussier than necessary, though. +In practice, unless you're meticulous about storage layout within a +data structure, a slice itself—using empty brackets with no size—is all you need:

     s := sum([]int{1,2,3})
@@ -470,8 +477,8 @@ sort of open/close/read/write interface.  Here's the start of file.go
 12    type File struct {
-13        fd      int    // file descriptor number
-14        name    string // file name at Open time
+13        fd   int    // file descriptor number
+14        name string // file name at Open time
 15    }
 

@@ -524,7 +531,7 @@ object. We could write return n

-but for simple structures like File it's easier to return the address of a nonce +but for simple structures like File it's easier to return the address of a composite literal, as is done here on line 21.

We can use the factory to construct some familiar, exported variables of type *File: @@ -541,7 +548,7 @@ The newFile function was not exported because it's internal. The pr exported factory to use is Open:

 
-30    func Open(name string, mode int, perm int) (file *File, err os.Error) {
+30    func Open(name string, mode int, perm uint32) (file *File, err os.Error) {
 31        r, e := syscall.Open(name, mode, perm)
 32        if e != 0 {
 33            err = os.Errno(e)
@@ -581,7 +588,7 @@ each of which declares a receiver variable file.
 40            return os.EINVAL
 41        }
 42        e := syscall.Close(file.fd)
-43        file.fd = -1  // so it can't be closed again
+43        file.fd = -1 // so it can't be closed again
 44        if e != 0 {
 45            return os.Errno(e)
 46        }
@@ -642,24 +649,30 @@ We can now use our new package:
 13    func main() {
 14        hello := []byte("hello, world\n")
 15        file.Stdout.Write(hello)
-16        file, err := file.Open("/does/not/exist",  0,  0)
-17        if file == nil {
+16        f, err := file.Open("/does/not/exist",  0,  0)
+17        if f == nil {
 18            fmt.Printf("can't open file; err=%s\n",  err.String())
 19            os.Exit(1)
 20        }
 21    }
 

-The ''./'' in the import of ''./file'' tells the compiler to use our own package rather than +The ''./'' in the import of ''./file'' tells the compiler +to use our own package rather than something from the directory of installed packages. +(Also, ''file.go'' must be compiled before we can import the +package.)

-Finally we can run the program: +Now we can compile and run the program:

-    % helloworld3
+    $ 6g file.go                       # compile file package
+    $ 6g helloworld3.go                # compile main package
+    $ 6l -o helloworld3 helloworld3.6  # link - no need to mention "file"
+    $ helloworld3
     hello, world
     can't open file; err=No such file or directory
-    %
+    $
 

Rotting cats

@@ -681,11 +694,11 @@ Building on the file package, here's a simple version of the Unix u 15 const NBUF = 512 16 var buf [NBUF]byte 17 for { -18 switch nr, er := f.Read(&buf); true { +18 switch nr, er := f.Read(buf[:]); true { 19 case nr < 0: 20 fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()) 21 os.Exit(1) -22 case nr == 0: // EOF +22 case nr == 0: // EOF 23 return 24 case nr > 0: 25 if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr { @@ -696,7 +709,7 @@ Building on the file package, here's a simple version of the Unix u 30 }

32 func main() { -33 flag.Parse() // Scans the arg list and sets up flags +33 flag.Parse() // Scans the arg list and sets up flags 34 if flag.NArg() == 0 { 35 cat(file.Stdin) 36 } @@ -757,7 +770,7 @@ we have a second implementation of the reader interface.

 
 31    type rotate13 struct {
-32        source    reader
+32        source reader
 33    }
 

35 func newRotate13(source reader) *rotate13 { @@ -797,11 +810,11 @@ and use it from within a mostly unchanged cat() function: 57 r = newRotate13(r) 58 } 59 for { -60 switch nr, er := r.Read(&buf); { +60 switch nr, er := r.Read(buf[:]); { 61 case nr < 0: 62 fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()) 63 os.Exit(1) -64 case nr == 0: // EOF +64 case nr == 0: // EOF 65 return 66 case nr > 0: 67 nw, ew := file.Stdout.Write(buf[0:nr]) @@ -823,11 +836,11 @@ even though under the covers it holds a pointer to a struct. Here it is in action:

-    % echo abcdefghijklmnopqrstuvwxyz | ./cat
+    $ echo abcdefghijklmnopqrstuvwxyz | ./cat
     abcdefghijklmnopqrstuvwxyz
-    % echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
+    $ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
     nopqrstuvwxyzabcdefghijklm
-    %
+    $
 

Fans of dependency injection may take cheer from how easily interfaces -- cgit v1.2.3