diff options
| -rw-r--r-- | doc/go_tutorial.html | 351 | ||||
| -rw-r--r-- | doc/go_tutorial.txt | 48 | ||||
| -rw-r--r-- | doc/progs/cat.go | 34 | ||||
| -rw-r--r-- | doc/progs/cat_rot13.go | 46 | ||||
| -rw-r--r-- | doc/progs/echo.go | 16 | ||||
| -rw-r--r-- | doc/progs/file.go | 32 | ||||
| -rw-r--r-- | doc/progs/helloworld.go | 2 | ||||
| -rw-r--r-- | doc/progs/helloworld3.go | 16 | ||||
| -rw-r--r-- | doc/progs/print.go | 19 | ||||
| -rw-r--r-- | doc/progs/print_string.go | 7 | ||||
| -rw-r--r-- | doc/progs/server.go | 38 | ||||
| -rw-r--r-- | doc/progs/server1.go | 40 | ||||
| -rw-r--r-- | doc/progs/sieve.go | 14 | ||||
| -rw-r--r-- | doc/progs/sieve1.go | 30 | ||||
| -rw-r--r-- | doc/progs/sort.go | 44 | ||||
| -rw-r--r-- | doc/progs/sortmain.go | 56 | ||||
| -rw-r--r-- | doc/progs/strings.go | 8 | ||||
| -rw-r--r-- | doc/progs/sum.go | 6 | 
18 files changed, 421 insertions, 386 deletions
| diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html index f3715f3bd..9576feee7 100644 --- a/doc/go_tutorial.html +++ b/doc/go_tutorial.html @@ -30,7 +30,7 @@ Let's start in the usual way:  07    import fmt "fmt"  // Package implementing formatted I/O.  <p>  09    func main() { -10        fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n"); +10        fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")  11    }  </pre>  <p> @@ -55,6 +55,32 @@ The comment convention is the same as in C++:  <p>  Later we'll have much more to say about printing.  <p> +<h2>Semicolons</h2> +<p> +You might have noticed that our program has no semicolons.  In Go +code, the only place you typically see semicolons is separating the +clauses of <code>for</code> loops and the like; they are not necessary after +every statement. +<p> +In fact, what happens is that the formal language uses semicolons, +much as in C or Java, but they are inserted automatically +at the end of every line that looks like the end of a statement. You +don't need to type them yourself. +<p> +For details about how this is done you can see the language +specification, but in practice all you need to know is that you +never need to put a semicolon at the end of a line.  (You can put +them in if you want to write multiple statements per line.) As an +extra help, you can also leave out a semicolon immediately before +a closing brace. +<p> +This approach makes for clean-looking, semicolon-free code.  The +one surprise is that it's important to put the opening +brace of a construct such as an <code>if</code> statement on the same line as +the <code>if</code>; if you don't, there are situations that may not compile +or may give the wrong result.  The language forces the brace style +to some extent. +<p>  <h2>Compiling</h2>  <p>  Go is a compiled language.  At the moment there are two compilers. @@ -92,30 +118,30 @@ Next up, here's a version of the Unix utility <code>echo(1)</code>:  05    package main  <p>  07    import ( -08        "os"; -09        "flag";  // command line option parser +08        "os" +09        "flag"  // command line option parser  10    )  <p>  12    var omitNewline = flag.Bool("n", false, "don't print final newline")  <p>  14    const ( -15        Space = " "; -16        Newline = "\n"; +15        Space = " " +16        Newline = "\n"  17    )  <p>  19    func main() { -20        flag.Parse();   // Scans the arg list and sets up flags -21        var s string = ""; +20        flag.Parse()   // Scans the arg list and sets up flags +21        var s string = ""  22        for i := 0; i < flag.NArg(); i++ {  23            if i > 0 {  24                s += Space  25            } -26            s += flag.Arg(i); +26            s += flag.Arg(i)  27        }  28        if !*omitNewline {  29            s += Newline  30        } -31        os.Stdout.WriteString(s); +31        os.Stdout.WriteString(s)  32    }  </pre>  <p> @@ -123,7 +149,7 @@ This program is small but it's doing a number of new things.  In the last exampl  we saw <code>func</code> introduce a function.  The keywords <code>var</code>, <code>const</code>, and <code>type</code>  (not used yet) also introduce declarations, as does <code>import</code>.  Notice that we can group declarations of the same sort into -parenthesized, semicolon-separated lists if we want, as on lines 7-10 and 14-17. +parenthesized lists, one item per line, as on lines 7-10 and 14-17.  But it's not necessary to do so; we could have said  <p>  <pre> @@ -131,21 +157,6 @@ But it's not necessary to do so; we could have said      const Newline = "\n"  </pre>  <p> -Semicolons aren't needed here; in fact, semicolons are unnecessary after any -top-level declaration, although they are needed as separators <i>within</i> -a parenthesized list of declarations. -<p> -You can use semicolons just the way you would in C, C++, or Java, but if you -prefer you can also leave them out in many cases.   They <i>separate</i> statements -rather than terminate them, so they aren't needed (but are still OK) at the end of the last -statement in a block. -They're also optional after braces, as in C. -Have a look at the source to <code>echo</code>. -The only necessary semicolons in that program are on lines 8, 15, and 21 -and of course between the elements of the <code>for</code> loop on line 22. -The ones on line 9, 16, 26, and 31 are optional but are there because a semicolon -on the end of a list of statements makes it easier to edit the list later. -<p>  This program imports the <code>"os"</code> package to access its <code>Stdout</code> variable, of type  <code>*os.File</code>.  The <code>import</code> statement is actually a declaration: in its general form,  as used in our ``hello world'' program, @@ -242,11 +253,11 @@ of course you can change a string <i>variable</i> simply by  reassigning it.  This snippet from <code>strings.go</code> is legal code:  <p>  <pre> <!-- progs/strings.go /hello/ /ciao/ --> -11        s := "hello"; +11        s := "hello"  12        if s[1] != 'e' { os.Exit(1) } -13        s = "good bye"; -14        var p *string = &s; -15        *p = "ciao"; +13        s = "good bye" +14        var p *string = &s +15        *p = "ciao"  </pre>  <p>  However the following statements are illegal because they would modify @@ -302,7 +313,7 @@ Using slices one can write this function (from <code>sum.go</code>):  <p>  <pre> <!-- progs/sum.go /sum/ /^}/ -->  09    func sum(a []int) int {   // returns an int -10        s := 0; +10        s := 0  11        for i := 0; i < len(a); i++ {  12            s += a[i]  13        } @@ -313,7 +324,7 @@ Using slices one can write this function (from <code>sum.go</code>):  and invoke it like this:  <p>  <pre> <!-- progs/sum.go /1,2,3/ --> -19        s := sum(&[3]int{1,2,3});  // a slice of the array is passed to sum +19        s := sum(&[3]int{1,2,3})  // a slice of the array is passed to sum  </pre>  <p>  Note how the return type (<code>int</code>) is defined for <code>sum()</code> by stating it @@ -454,13 +465,13 @@ sort of open/close/read/write interface.  Here's the start of <code>file.go</cod  05    package file  <p>  07    import ( -08        "os"; -09        "syscall"; +08        "os" +09        "syscall"  10    )  <p>  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    }  </pre>  <p> @@ -520,9 +531,9 @@ We can use the factory to construct some familiar, exported variables of type <c  <p>  <pre> <!-- progs/file.go /var/ /^.$/ -->  24    var ( -25        Stdin  = newFile(0, "/dev/stdin"); -26        Stdout = newFile(1, "/dev/stdout"); -27        Stderr = newFile(2, "/dev/stderr"); +25        Stdin  = newFile(0, "/dev/stdin") +26        Stdout = newFile(1, "/dev/stdout") +27        Stderr = newFile(2, "/dev/stderr")  28    )  </pre>  <p> @@ -531,9 +542,9 @@ exported factory to use is <code>Open</code>:  <p>  <pre> <!-- progs/file.go /func.Open/ /^}/ -->  30    func Open(name string, mode int, perm int) (file *File, err os.Error) { -31        r, e := syscall.Open(name, mode, perm); +31        r, e := syscall.Open(name, mode, perm)  32        if e != 0 { -33            err = os.Errno(e); +33            err = os.Errno(e)  34        }  35        return newFile(r, name), err  36    } @@ -569,10 +580,10 @@ each of which declares a receiver variable <code>file</code>.  39        if file == nil {  40            return os.EINVAL  41        } -42        e := syscall.Close(file.fd); -43        file.fd = -1;  // so it can't be closed again +42        e := syscall.Close(file.fd) +43        file.fd = -1  // so it can't be closed again  44        if e != 0 { -45            return os.Errno(e); +45            return os.Errno(e)  46        }  47        return nil  48    } @@ -581,9 +592,9 @@ each of which declares a receiver variable <code>file</code>.  51        if file == nil {  52            return -1, os.EINVAL  53        } -54        r, e := syscall.Read(file.fd, b); +54        r, e := syscall.Read(file.fd, b)  55        if e != 0 { -56            err = os.Errno(e); +56            err = os.Errno(e)  57        }  58        return int(r), err  59    } @@ -592,9 +603,9 @@ each of which declares a receiver variable <code>file</code>.  62        if file == nil {  63            return -1, os.EINVAL  64        } -65        r, e := syscall.Write(file.fd, b); +65        r, e := syscall.Write(file.fd, b)  66        if e != 0 { -67            err = os.Errno(e); +67            err = os.Errno(e)  68        }  69        return int(r), err  70    } @@ -623,18 +634,18 @@ We can now use our new package:  05    package main  <p>  07    import ( -08        "./file"; -09        "fmt"; -10        "os"; +08        "./file" +09        "fmt" +10        "os"  11    )  <p>  13    func main() { -14        hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'}; -15        file.Stdout.Write(hello); -16        file, err := file.Open("/does/not/exist",  0,  0); +14        hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'} +15        file.Stdout.Write(hello) +16        file, err := file.Open("/does/not/exist",  0,  0)  17        if file == nil { -18            fmt.Printf("can't open file; err=%s\n",  err.String()); -19            os.Exit(1); +18            fmt.Printf("can't open file; err=%s\n",  err.String()) +19            os.Exit(1)  20        }  21    }  </pre> @@ -660,43 +671,43 @@ Building on the <code>file</code> package, here's a simple version of the Unix u  05    package main  <p>  07    import ( -08        "./file"; -09        "flag"; -10        "fmt"; -11        "os"; +08        "./file" +09        "flag" +10        "fmt" +11        "os"  12    )  <p>  14    func cat(f *file.File) { -15        const NBUF = 512; -16        var buf [NBUF]byte; +15        const NBUF = 512 +16        var buf [NBUF]byte  17        for {  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); +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 -23                return; +23                return  24            case nr > 0:  25                if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr { -26                    fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String()); +26                    fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String())  27                }  28            }  29        }  30    }  <p>  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); +35            cat(file.Stdin)  36        }  37        for i := 0; i < flag.NArg(); i++ { -38            f, err := file.Open(flag.Arg(i), 0, 0); +38            f, err := file.Open(flag.Arg(i), 0, 0)  39            if f == nil { -40                fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err); -41                os.Exit(1); +40                fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) +41                os.Exit(1)  42            } -43            cat(f); -44            f.Close(); +43            cat(f) +44            f.Close()  45        }  46    }  </pre> @@ -729,8 +740,8 @@ Here is code from <code>progs/cat_rot13.go</code>:  <p>  <pre> <!-- progs/cat_rot13.go /type.reader/ /^}/ -->  26    type reader interface { -27        Read(b []byte) (ret int, err os.Error); -28        String() string; +27        Read(b []byte) (ret int, err os.Error) +28        String() string  29    }  </pre>  <p> @@ -746,7 +757,7 @@ we have a second implementation of the <code>reader</code> interface.  <p>  <pre> <!-- progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/ -->  31    type rotate13 struct { -32        source    reader; +32        source    reader  33    }  <p>  35    func newRotate13(source reader) *rotate13 { @@ -754,7 +765,7 @@ we have a second implementation of the <code>reader</code> interface.  37    }  <p>  39    func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) { -40        r, e := r13.source.Read(b); +40        r, e := r13.source.Read(b)  41        for i := 0; i < r; i++ {  42            b[i] = rot13(b[i])  43        } @@ -779,8 +790,8 @@ and use it from within a mostly unchanged <code>cat()</code> function:  <p>  <pre> <!-- progs/cat_rot13.go /func.cat/ /^}/ -->  52    func cat(r reader) { -53        const NBUF = 512; -54        var buf [NBUF]byte; +53        const NBUF = 512 +54        var buf [NBUF]byte  <p>  56        if *rot13Flag {  57            r = newRotate13(r) @@ -788,14 +799,14 @@ and use it from within a mostly unchanged <code>cat()</code> function:  59        for {  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); +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 -65                return; +65                return  66            case nr > 0: -67                nw, ew := file.Stdout.Write(buf[0:nr]); +67                nw, ew := file.Stdout.Write(buf[0:nr])  68                if nw != nr { -69                    fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String()); +69                    fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String())  70                }  71            }  72        } @@ -851,7 +862,7 @@ As an example, consider this simple sort algorithm taken from <code>progs/sort.g  13    func Sort(data Interface) {  14        for i := 1; i < data.Len(); i++ {  15            for j := i; j > 0 && data.Less(j, j-1); j-- { -16                data.Swap(j, j-1); +16                data.Swap(j, j-1)  17            }  18        }  19    } @@ -861,9 +872,9 @@ The code needs only three methods, which we wrap into sort's <code>Interface</co  <p>  <pre> <!-- progs/sort.go /interface/ /^}/ -->  07    type Interface interface { -08        Len() int; -09        Less(i, j int) bool; -10        Swap(i, j int); +08        Len() int +09        Less(i, j int) bool +10        Swap(i, j int)  11    }  </pre>  <p> @@ -874,9 +885,9 @@ arrays of integers, strings, etc.; here's the code for arrays of <code>int</code  <pre> <!-- progs/sort.go /type.*IntArray/ /Swap/ -->  33    type IntArray []int  <p> -35    func (p IntArray) Len() int            { return len(p); } -36    func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; } -37    func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; } +35    func (p IntArray) Len() int            { return len(p) } +36    func (p IntArray) Less(i, j int) bool  { return p[i] < p[j] } +37    func (p IntArray) 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 @@ -888,9 +899,9 @@ to test that the result is sorted.  <p>  <pre> <!-- progs/sortmain.go /func.ints/ /^}/ -->  12    func ints() { -13        data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}; -14        a := sort.IntArray(data); -15        sort.Sort(a); +13        data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586} +14        a := sort.IntArray(data) +15        sort.Sort(a)  16        if !sort.IsSorted(a) {  17            panic()  18        } @@ -902,18 +913,18 @@ to implement the three methods for that type, like this:  <p>  <pre> <!-- progs/sortmain.go /type.day/ /Swap/ -->  30    type day struct { -31        num        int; -32        shortName  string; -33        longName   string; +31        num        int +32        shortName  string +33        longName   string  34    }  <p>  36    type dayArray struct { -37        data []*day; +37        data []*day  38    }  <p> -40    func (p *dayArray) Len() int            { return len(p.data); } -41    func (p *dayArray) Less(i, j int) bool  { return p.data[i].num < p.data[j].num; } -42    func (p *dayArray) Swap(i, j int)       { p.data[i], p.data[j] = p.data[j], p.data[i]; } +40    func (p *dayArray) Len() int            { return len(p.data) } +41    func (p *dayArray) Less(i, j int) bool  { return p.data[i].num < p.data[j].num } +42    func (p *dayArray) Swap(i, j int)       { p.data[i], p.data[j] = p.data[j], p.data[i] }  </pre>  <p>  <p> @@ -944,8 +955,8 @@ can just say <code>%d</code>; <code>Printf</code> knows the size and signedness  integer and can do the right thing for you.  The snippet  <p>  <pre> <!-- progs/print.go NR==10 NR==11 --> -10        var u64 uint64 = 1<<64-1; -11        fmt.Printf("%d %d\n", u64, int64(u64)); +10        var u64 uint64 = 1<<64-1 +11        fmt.Printf("%d %d\n", u64, int64(u64))  </pre>  <p>  prints @@ -957,11 +968,14 @@ prints  In fact, if you're lazy the format <code>%v</code> will print, in a simple  appropriate style, any value, even an array or structure.  The output of  <p> -<pre> <!-- progs/print.go NR==14 NR==17 --> -14        type T struct { a int; b string }; -15        t := T{77, "Sunset Strip"}; -16        a := []int{1, 2, 3, 4}; -17        fmt.Printf("%v %v %v\n", u64, t, a); +<pre> <!-- progs/print.go NR==14 NR==20 --> +14        type T struct { +15            a int +16            b string +17        } +18        t := T{77, "Sunset Strip"} +19        a := []int{1, 2, 3, 4} +20        fmt.Printf("%v %v %v\n", u64, t, a)  </pre>  <p>  is @@ -977,9 +991,9 @@ of <code>%v</code> while <code>Println</code> inserts spaces between arguments  and adds a newline.  The output of each of these two lines is identical  to that of the <code>Printf</code> call above.  <p> -<pre> <!-- progs/print.go NR==18 NR==19 --> -18        fmt.Print(u64, " ", t, " ", a, "\n"); -19        fmt.Println(u64, t, a); +<pre> <!-- progs/print.go NR==21 NR==22 --> +21        fmt.Print(u64, " ", t, " ", a, "\n") +22        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, @@ -989,16 +1003,19 @@ the method and if so, use it rather than some other formatting.  Here's a simple example.  <p>  <pre> <!-- progs/print_string.go NR==9 END --> -09    type testType struct { a int; b string } +09    type testType struct { +10        a int +11        b string +12    }  <p> -11    func (t *testType) String() string { -12        return fmt.Sprint(t.a) + " " + t.b -13    } +14    func (t *testType) String() string { +15        return fmt.Sprint(t.a) + " " + t.b +16    }  <p> -15    func main() { -16        t := &testType{77, "Sunset Strip"}; -17        fmt.Println(t) -18    } +18    func main() { +19        t := &testType{77, "Sunset Strip"} +20        fmt.Println(t) +21    }  </pre>  <p>  Since <code>*testType</code> has a <code>String()</code> method, the @@ -1128,7 +1145,7 @@ operator <code><-</code> (receive) retrieves the next value on the channel.  17    // removing those divisible by 'prime'.  18    func filter(in, out chan int, prime int) {  19        for { -20            i := <-in;  // Receive value of new variable 'i' from 'in'. +20            i := <-in  // Receive value of new variable 'i' from 'in'.  21            if i % prime != 0 {  22                out <- i  // Send 'i' to channel 'out'.  23            } @@ -1163,13 +1180,13 @@ together:  <p>  <pre> <!-- progs/sieve.go /func.main/ /^}/ -->  28    func main() { -29        ch := make(chan int);  // Create a new channel. -30        go generate(ch);  // Start generate() as a goroutine. +29        ch := make(chan int)  // Create a new channel. +30        go generate(ch)  // Start generate() as a goroutine.  31        for { -32            prime := <-ch; -33            fmt.Println(prime); -34            ch1 := make(chan int); -35            go filter(ch, ch1, prime); +32            prime := <-ch +33            fmt.Println(prime) +34            ch1 := make(chan int) +35            go filter(ch, ch1, prime)  36            ch = ch1  37        }  38    } @@ -1186,13 +1203,13 @@ of <code>generate</code>, from <code>progs/sieve1.go</code>:  <p>  <pre> <!-- progs/sieve1.go /func.generate/ /^}/ -->  10    func generate() chan int { -11        ch := make(chan int); +11        ch := make(chan int)  12        go func(){  13            for i := 2; ; i++ {  14                ch <- i  15            } -16        }(); -17        return ch; +16        }() +17        return ch  18    }  </pre>  <p> @@ -1210,15 +1227,15 @@ The same change can be made to <code>filter</code>:  <p>  <pre> <!-- progs/sieve1.go /func.filter/ /^}/ -->  21    func filter(in chan int, prime int) chan int { -22        out := make(chan int); +22        out := make(chan int)  23        go func() {  24            for {  25                if i := <-in; i % prime != 0 {  26                    out <- i  27                }  28            } -29        }(); -30        return out; +29        }() +30        return out  31    }  </pre>  <p> @@ -1227,16 +1244,16 @@ result, and while we're at it let's turn it into a factory too:  <p>  <pre> <!-- progs/sieve1.go /func.sieve/ /^}/ -->  33    func sieve() chan int { -34        out := make(chan int); +34        out := make(chan int)  35        go func() { -36            ch := generate(); +36            ch := generate()  37            for { -38                prime := <-ch; -39                out <- prime; -40                ch = filter(ch, prime); +38                prime := <-ch +39                out <- prime +40                ch = filter(ch, prime)  41            } -42        }(); -43        return out; +42        }() +43        return out  44    }  </pre>  <p> @@ -1244,9 +1261,9 @@ Now <code>main</code>'s interface to the prime sieve is a channel of primes:  <p>  <pre> <!-- progs/sieve1.go /func.main/ /^}/ -->  46    func main() { -47        primes := sieve(); +47        primes := sieve()  48        for { -49            fmt.Println(<-primes); +49            fmt.Println(<-primes)  50        }  51    }  </pre> @@ -1262,8 +1279,8 @@ that will be used for the reply.  <p>  <pre> <!-- progs/server.go /type.request/ /^}/ -->  09    type request struct { -10        a, b    int; -11        replyc  chan int; +10        a, b    int +11        replyc  chan int  12    }  </pre>  <p> @@ -1274,8 +1291,8 @@ code that invokes the operation and responds to the request:  14    type binOp func(a, b int) int  <p>  16    func run(op binOp, req *request) { -17        reply := op(req.a, req.b); -18        req.replyc <- reply; +17        reply := op(req.a, req.b) +18        req.replyc <- reply  19    }  </pre>  <p> @@ -1288,8 +1305,8 @@ a long-running operation, starting a goroutine to do the actual work.  <pre> <!-- progs/server.go /func.server/ /^}/ -->  21    func server(op binOp, service chan *request) {  22        for { -23            req := <-service; -24            go run(op, req);  // don't wait for it +23            req := <-service +24            go run(op, req)  // don't wait for it  25        }  26    }  </pre> @@ -1299,9 +1316,9 @@ connected to it:  <p>  <pre> <!-- progs/server.go /func.startServer/ /^}/ -->  28    func startServer(op binOp) chan *request { -29        req := make(chan *request); -30        go server(op, req); -31        return req; +29        req := make(chan *request) +30        go server(op, req) +31        return req  32    }  </pre>  <p> @@ -1311,22 +1328,22 @@ does it check the results.  <p>  <pre> <!-- progs/server.go /func.main/ /^}/ -->  34    func main() { -35        adder := startServer(func(a, b int) int { return a + b }); -36        const N = 100; -37        var reqs [N]request; +35        adder := startServer(func(a, b int) int { return a + b }) +36        const N = 100 +37        var reqs [N]request  38        for i := 0; i < N; i++ { -39            req := &reqs[i]; -40            req.a = i; -41            req.b = i + N; -42            req.replyc = make(chan int); -43            adder <- req; +39            req := &reqs[i] +40            req.a = i +41            req.b = i + N +42            req.replyc = make(chan int) +43            adder <- req  44        }  45        for i := N-1; i >= 0; i-- {   // doesn't matter what order  46            if <-reqs[i].replyc != N + 2*i { -47                fmt.Println("fail at", i); +47                fmt.Println("fail at", i)  48            }  49        } -50        fmt.Println("done"); +50        fmt.Println("done")  51    }  </pre>  <p> @@ -1336,10 +1353,10 @@ we can provide a second, <code>quit</code> channel to the server:  <p>  <pre> <!-- progs/server1.go /func.startServer/ /^}/ -->  32    func startServer(op binOp) (service chan *request, quit chan bool) { -33        service = make(chan *request); -34        quit = make(chan bool); -35        go server(op, service, quit); -36        return service, quit; +33        service = make(chan *request) +34        quit = make(chan bool) +35        go server(op, service, quit) +36        return service, quit  37    }  </pre>  <p> @@ -1350,9 +1367,9 @@ It passes the quit channel to the <code>server</code> function, which uses it li  22        for {  23            select {  24            case req := <-service: -25                go run(op, req);  // don't wait for it +25                go run(op, req)  // don't wait for it  26            case <-quit: -27                return; +27                return  28            }  29        }  30    } @@ -1369,11 +1386,11 @@ All that's left is to strobe the <code>quit</code> channel  at the end of main:  <p>  <pre> <!-- progs/server1.go /adder,.quit/ --> -40        adder, quit := startServer(func(a, b int) int { return a + b }); +40        adder, quit := startServer(func(a, b int) int { return a + b })  </pre>  ...  <pre> <!-- progs/server1.go /quit....true/ --> -55        quit <- true; +55        quit <- true  </pre>  <p>  There's a lot more to Go programming and concurrent programming in general but this diff --git a/doc/go_tutorial.txt b/doc/go_tutorial.txt index 7c0ffac80..93344257f 100644 --- a/doc/go_tutorial.txt +++ b/doc/go_tutorial.txt @@ -47,6 +47,33 @@ The comment convention is the same as in C++:  Later we'll have much more to say about printing. +Semicolons +---- + +You might have noticed that our program has no semicolons.  In Go +code, the only place you typically see semicolons is separating the +clauses of "for" loops and the like; they are not necessary after +every statement. + +In fact, what happens is that the formal language uses semicolons, +much as in C or Java, but they are inserted automatically +at the end of every line that looks like the end of a statement. You +don't need to type them yourself. + +For details about how this is done you can see the language +specification, but in practice all you need to know is that you +never need to put a semicolon at the end of a line.  (You can put +them in if you want to write multiple statements per line.) As an +extra help, you can also leave out a semicolon immediately before +a closing brace. + +This approach makes for clean-looking, semicolon-free code.  The +one surprise is that it's important to put the opening +brace of a construct such as an "if" statement on the same line as +the "if"; if you don't, there are situations that may not compile +or may give the wrong result.  The language forces the brace style +to some extent. +  Compiling  ---- @@ -84,27 +111,12 @@ This program is small but it's doing a number of new things.  In the last exampl  we saw "func" introduce a function.  The keywords "var", "const", and "type"  (not used yet) also introduce declarations, as does "import".  Notice that we can group declarations of the same sort into -parenthesized, semicolon-separated lists if we want, as on lines 7-10 and 14-17. +parenthesized lists, one item per line, as on lines 7-10 and 14-17.  But it's not necessary to do so; we could have said  	const Space = " "  	const Newline = "\n" -Semicolons aren't needed here; in fact, semicolons are unnecessary after any -top-level declaration, although they are needed as separators <i>within</i> -a parenthesized list of declarations. - -You can use semicolons just the way you would in C, C++, or Java, but if you -prefer you can also leave them out in many cases.   They <i>separate</i> statements -rather than terminate them, so they aren't needed (but are still OK) at the end of the last -statement in a block. -They're also optional after braces, as in C. -Have a look at the source to "echo". -The only necessary semicolons in that program are on lines 8, 15, and 21 -and of course between the elements of the "for" loop on line 22. -The ones on line 9, 16, 26, and 31 are optional but are there because a semicolon -on the end of a list of statements makes it easier to edit the list later. -  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, @@ -634,7 +646,7 @@ prints  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 ---PROG progs/print.go 'NR==14' 'NR==17' +--PROG progs/print.go 'NR==14' 'NR==20'  is @@ -647,7 +659,7 @@ of "%v" while "Println" inserts spaces between arguments  and adds a newline.  The output of each of these two lines is identical  to that of the "Printf" call above. ---PROG progs/print.go 'NR==18' 'NR==19' +--PROG progs/print.go 'NR==21' 'NR==22'  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 diff --git a/doc/progs/cat.go b/doc/progs/cat.go index 4e5e31cae..f8d1a54fb 100644 --- a/doc/progs/cat.go +++ b/doc/progs/cat.go @@ -5,42 +5,42 @@  package main  import ( -	"./file"; -	"flag"; -	"fmt"; -	"os"; +	"./file" +	"flag" +	"fmt" +	"os"  )  func cat(f *file.File) { -	const NBUF = 512; -	var buf [NBUF]byte; +	const NBUF = 512 +	var buf [NBUF]byte  	for {  		switch nr, er := f.Read(&buf); true {  		case nr < 0: -			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()); -			os.Exit(1); +			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()) +			os.Exit(1)  		case nr == 0:  // EOF -			return; +			return  		case nr > 0:  			if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr { -				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String()); +				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String())  			}  		}  	}  }  func main() { -	flag.Parse();   // Scans the arg list and sets up flags +	flag.Parse()   // Scans the arg list and sets up flags  	if flag.NArg() == 0 { -		cat(file.Stdin); +		cat(file.Stdin)  	}  	for i := 0; i < flag.NArg(); i++ { -		f, err := file.Open(flag.Arg(i), 0, 0); +		f, err := file.Open(flag.Arg(i), 0, 0)  		if f == nil { -			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err); -			os.Exit(1); +			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) +			os.Exit(1)  		} -		cat(f); -		f.Close(); +		cat(f) +		f.Close()  	}  } diff --git a/doc/progs/cat_rot13.go b/doc/progs/cat_rot13.go index 555cecdf4..42c6195fb 100644 --- a/doc/progs/cat_rot13.go +++ b/doc/progs/cat_rot13.go @@ -5,17 +5,17 @@  package main  import ( -	"./file"; -	"flag"; -	"fmt"; -	"os"; +	"./file" +	"flag" +	"fmt" +	"os"  )  var rot13Flag = flag.Bool("rot13", false, "rot13 the input")  func rot13(b byte) byte {  	if 'a' <= b && b <= 'z' { -	   b = 'a' + ((b - 'a') + 13) % 26; +	   b = 'a' + ((b - 'a') + 13) % 26  	}  	if 'A' <= b && b <= 'Z' {  	   b = 'A' + ((b - 'A') + 13) % 26 @@ -24,12 +24,12 @@ func rot13(b byte) byte {  }  type reader interface { -	Read(b []byte) (ret int, err os.Error); -	String() string; +	Read(b []byte) (ret int, err os.Error) +	String() string  }  type rotate13 struct { -	source	reader; +	source	reader  }  func newRotate13(source reader) *rotate13 { @@ -37,7 +37,7 @@ func newRotate13(source reader) *rotate13 {  }  func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) { -	r, e := r13.source.Read(b); +	r, e := r13.source.Read(b)  	for i := 0; i < r; i++ {  		b[i] = rot13(b[i])  	} @@ -50,8 +50,8 @@ func (r13 *rotate13) String() string {  // end of rotate13 implementation  func cat(r reader) { -	const NBUF = 512; -	var buf [NBUF]byte; +	const NBUF = 512 +	var buf [NBUF]byte  	if *rot13Flag {  		r = newRotate13(r) @@ -59,31 +59,31 @@ func cat(r reader) {  	for {  		switch nr, er := r.Read(&buf); {  		case nr < 0: -			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()); -			os.Exit(1); +			fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()) +			os.Exit(1)  		case nr == 0:  // EOF -			return; +			return  		case nr > 0: -			nw, ew := file.Stdout.Write(buf[0:nr]); +			nw, ew := file.Stdout.Write(buf[0:nr])  			if nw != nr { -				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String()); +				fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String())  			}  		}  	}  }  func main() { -	flag.Parse();   // Scans the arg list and sets up flags +	flag.Parse()   // Scans the arg list and sets up flags  	if flag.NArg() == 0 { -		cat(file.Stdin); +		cat(file.Stdin)  	}  	for i := 0; i < flag.NArg(); i++ { -		f, err := file.Open(flag.Arg(i), 0, 0); +		f, err := file.Open(flag.Arg(i), 0, 0)  		if f == nil { -			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err); -			os.Exit(1); +			fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) +			os.Exit(1)  		} -		cat(f); -		f.Close(); +		cat(f) +		f.Close()  	}  } diff --git a/doc/progs/echo.go b/doc/progs/echo.go index 4761c1e97..84470ddb9 100644 --- a/doc/progs/echo.go +++ b/doc/progs/echo.go @@ -5,28 +5,28 @@  package main  import ( -	"os"; -	"flag";  // command line option parser +	"os" +	"flag"  // command line option parser  )  var omitNewline = flag.Bool("n", false, "don't print final newline")  const ( -	Space = " "; -	Newline = "\n"; +	Space = " " +	Newline = "\n"  )  func main() { -	flag.Parse();   // Scans the arg list and sets up flags -	var s string = ""; +	flag.Parse()   // Scans the arg list and sets up flags +	var s string = ""  	for i := 0; i < flag.NArg(); i++ {  		if i > 0 {  			s += Space  		} -		s += flag.Arg(i); +		s += flag.Arg(i)  	}  	if !*omitNewline {  		s += Newline  	} -	os.Stdout.WriteString(s); +	os.Stdout.WriteString(s)  } diff --git a/doc/progs/file.go b/doc/progs/file.go index c55149421..b2f2c0476 100644 --- a/doc/progs/file.go +++ b/doc/progs/file.go @@ -5,13 +5,13 @@  package file  import ( -	"os"; -	"syscall"; +	"os" +	"syscall"  )  type File struct { -	fd      int;    // file descriptor number -	name    string; // file name at Open time +	fd      int    // file descriptor number +	name    string // file name at Open time  }  func newFile(fd int, name string) *File { @@ -22,15 +22,15 @@ func newFile(fd int, name string) *File {  }  var ( -	Stdin  = newFile(0, "/dev/stdin"); -	Stdout = newFile(1, "/dev/stdout"); -	Stderr = newFile(2, "/dev/stderr"); +	Stdin  = newFile(0, "/dev/stdin") +	Stdout = newFile(1, "/dev/stdout") +	Stderr = newFile(2, "/dev/stderr")  )  func Open(name string, mode int, perm int) (file *File, err os.Error) { -	r, e := syscall.Open(name, mode, perm); +	r, e := syscall.Open(name, mode, perm)  	if e != 0 { -		err = os.Errno(e); +		err = os.Errno(e)  	}  	return newFile(r, name), err  } @@ -39,10 +39,10 @@ func (file *File) Close() os.Error {  	if file == nil {  		return os.EINVAL  	} -	e := syscall.Close(file.fd); -	file.fd = -1;  // so it can't be closed again +	e := syscall.Close(file.fd) +	file.fd = -1  // so it can't be closed again  	if e != 0 { -		return os.Errno(e); +		return os.Errno(e)  	}  	return nil  } @@ -51,9 +51,9 @@ func (file *File) Read(b []byte) (ret int, err os.Error) {  	if file == nil {  		return -1, os.EINVAL  	} -	r, e := syscall.Read(file.fd, b); +	r, e := syscall.Read(file.fd, b)  	if e != 0 { -		err = os.Errno(e); +		err = os.Errno(e)  	}  	return int(r), err  } @@ -62,9 +62,9 @@ func (file *File) Write(b []byte) (ret int, err os.Error) {  	if file == nil {  		return -1, os.EINVAL  	} -	r, e := syscall.Write(file.fd, b); +	r, e := syscall.Write(file.fd, b)  	if e != 0 { -		err = os.Errno(e); +		err = os.Errno(e)  	}  	return int(r), err  } diff --git a/doc/progs/helloworld.go b/doc/progs/helloworld.go index c4c3855ed..637a0956b 100644 --- a/doc/progs/helloworld.go +++ b/doc/progs/helloworld.go @@ -7,5 +7,5 @@ package main  import fmt "fmt"  // Package implementing formatted I/O.  func main() { -	fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n"); +	fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")  } diff --git a/doc/progs/helloworld3.go b/doc/progs/helloworld3.go index ea567fe1b..5655c7489 100644 --- a/doc/progs/helloworld3.go +++ b/doc/progs/helloworld3.go @@ -5,17 +5,17 @@  package main  import ( -	"./file"; -	"fmt"; -	"os"; +	"./file" +	"fmt" +	"os"  )  func main() { -	hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'}; -	file.Stdout.Write(hello); -	file, err := file.Open("/does/not/exist",  0,  0); +	hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'} +	file.Stdout.Write(hello) +	file, err := file.Open("/does/not/exist",  0,  0)  	if file == nil { -		fmt.Printf("can't open file; err=%s\n",  err.String()); -		os.Exit(1); +		fmt.Printf("can't open file; err=%s\n",  err.String()) +		os.Exit(1)  	}  } diff --git a/doc/progs/print.go b/doc/progs/print.go index cc146fed8..69c35a532 100644 --- a/doc/progs/print.go +++ b/doc/progs/print.go @@ -7,14 +7,17 @@ package main  import "fmt"  func main() { -	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))  	// harder stuff -	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.Print(u64, " ", t, " ", a, "\n"); -	fmt.Println(u64, t, a); +	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.Print(u64, " ", t, " ", a, "\n") +	fmt.Println(u64, t, a)  } diff --git a/doc/progs/print_string.go b/doc/progs/print_string.go index 13a8d8241..46ab1d91a 100644 --- a/doc/progs/print_string.go +++ b/doc/progs/print_string.go @@ -6,13 +6,16 @@ package main  import "fmt" -type testType struct { a int; b string } +type testType struct { +	a int +	b string +}  func (t *testType) String() string {  	return fmt.Sprint(t.a) + " " + t.b  }  func main() { -	t := &testType{77, "Sunset Strip"}; +	t := &testType{77, "Sunset Strip"}  	fmt.Println(t)  } diff --git a/doc/progs/server.go b/doc/progs/server.go index 8906e9635..f3a6b1889 100644 --- a/doc/progs/server.go +++ b/doc/progs/server.go @@ -7,45 +7,45 @@ package main  import "fmt"  type request struct { -	a, b    int; -	replyc  chan int; +	a, b    int +	replyc  chan int  }  type binOp func(a, b int) int  func run(op binOp, req *request) { -	reply := op(req.a, req.b); -	req.replyc <- reply; +	reply := op(req.a, req.b) +	req.replyc <- reply  }  func server(op binOp, service chan *request) {  	for { -		req := <-service; -		go run(op, req);  // don't wait for it +		req := <-service +		go run(op, req)  // don't wait for it  	}  }  func startServer(op binOp) chan *request { -	req := make(chan *request); -	go server(op, req); -	return req; +	req := make(chan *request) +	go server(op, req) +	return req  }  func main() { -	adder := startServer(func(a, b int) int { return a + b }); -	const N = 100; -	var reqs [N]request; +	adder := startServer(func(a, b int) int { return a + b }) +	const N = 100 +	var reqs [N]request  	for i := 0; i < N; i++ { -		req := &reqs[i]; -		req.a = i; -		req.b = i + N; -		req.replyc = make(chan int); -		adder <- req; +		req := &reqs[i] +		req.a = i +		req.b = i + N +		req.replyc = make(chan int) +		adder <- req  	}  	for i := N-1; i >= 0; i-- {   // doesn't matter what order  		if <-reqs[i].replyc != N + 2*i { -			fmt.Println("fail at", i); +			fmt.Println("fail at", i)  		}  	} -	fmt.Println("done"); +	fmt.Println("done")  } diff --git a/doc/progs/server1.go b/doc/progs/server1.go index 591e27606..b8c09269b 100644 --- a/doc/progs/server1.go +++ b/doc/progs/server1.go @@ -7,50 +7,50 @@ package main  import "fmt"  type request struct { -	a, b	int; -	replyc	chan int; +	a, b	int +	replyc	chan int  }  type binOp func(a, b int) int  func run(op binOp, req *request) { -	reply := op(req.a, req.b); -	req.replyc <- reply; +	reply := op(req.a, req.b) +	req.replyc <- reply  }  func server(op binOp, service chan *request, quit chan bool) {  	for {  		select {  		case req := <-service: -			go run(op, req);  // don't wait for it +			go run(op, req)  // don't wait for it  		case <-quit: -			return; +			return  		}  	}  }  func startServer(op binOp) (service chan *request, quit chan bool) { -	service = make(chan *request); -	quit = make(chan bool); -	go server(op, service, quit); -	return service, quit; +	service = make(chan *request) +	quit = make(chan bool) +	go server(op, service, quit) +	return service, quit  }  func main() { -	adder, quit := startServer(func(a, b int) int { return a + b }); -	const N = 100; -	var reqs [N]request; +	adder, quit := startServer(func(a, b int) int { return a + b }) +	const N = 100 +	var reqs [N]request  	for i := 0; i < N; i++ { -		req := &reqs[i]; -		req.a = i; -		req.b = i + N; -		req.replyc = make(chan int); -		adder <- req; +		req := &reqs[i] +		req.a = i +		req.b = i + N +		req.replyc = make(chan int) +		adder <- req  	}  	for i := N-1; i >= 0; i-- {   // doesn't matter what order  		if <-reqs[i].replyc != N + 2*i { -			fmt.Println("fail at", i); +			fmt.Println("fail at", i)  		}  	} -	quit <- true; +	quit <- true  } diff --git a/doc/progs/sieve.go b/doc/progs/sieve.go index cd011d293..fb649e049 100644 --- a/doc/progs/sieve.go +++ b/doc/progs/sieve.go @@ -17,7 +17,7 @@ func generate(ch chan int) {  // removing those divisible by 'prime'.  func filter(in, out chan int, prime int) {  	for { -		i := <-in;  // Receive value of new variable 'i' from 'in'. +		i := <-in  // Receive value of new variable 'i' from 'in'.  		if i % prime != 0 {  			out <- i  // Send 'i' to channel 'out'.  		} @@ -26,13 +26,13 @@ func filter(in, out chan int, prime int) {  // The prime sieve: Daisy-chain filter processes together.  func main() { -	ch := make(chan int);  // Create a new channel. -	go generate(ch);  // Start generate() as a goroutine. +	ch := make(chan int)  // Create a new channel. +	go generate(ch)  // Start generate() as a goroutine.  	for { -		prime := <-ch; -		fmt.Println(prime); -		ch1 := make(chan int); -		go filter(ch, ch1, prime); +		prime := <-ch +		fmt.Println(prime) +		ch1 := make(chan int) +		go filter(ch, ch1, prime)  		ch = ch1  	}  } diff --git a/doc/progs/sieve1.go b/doc/progs/sieve1.go index 0ae3893ab..71468d06e 100644 --- a/doc/progs/sieve1.go +++ b/doc/progs/sieve1.go @@ -8,44 +8,44 @@ import "fmt"  // Send the sequence 2, 3, 4, ... to returned channel   func generate() chan int { -	ch := make(chan int); +	ch := make(chan int)  	go func(){  		for i := 2; ; i++ {  			ch <- i  		} -	}(); -	return ch; +	}() +	return ch  }  // Filter out input values divisible by 'prime', send rest to returned channel  func filter(in chan int, prime int) chan int { -	out := make(chan int); +	out := make(chan int)  	go func() {  		for {  			if i := <-in; i % prime != 0 {  				out <- i  			}  		} -	}(); -	return out; +	}() +	return out  }  func sieve() chan int { -	out := make(chan int); +	out := make(chan int)  	go func() { -		ch := generate(); +		ch := generate()  		for { -			prime := <-ch; -			out <- prime; -			ch = filter(ch, prime); +			prime := <-ch +			out <- prime +			ch = filter(ch, prime)  		} -	}(); -	return out; +	}() +	return out  }  func main() { -	primes := sieve(); +	primes := sieve()  	for { -		fmt.Println(<-primes); +		fmt.Println(<-primes)  	}  } diff --git a/doc/progs/sort.go b/doc/progs/sort.go index 5b16ad260..6738860d9 100644 --- a/doc/progs/sort.go +++ b/doc/progs/sort.go @@ -5,59 +5,59 @@  package sort  type Interface interface { -	Len() int; -	Less(i, j int) bool; -	Swap(i, j int); +	Len() int +	Less(i, j int) bool +	Swap(i, j int)  }  func Sort(data Interface) {  	for i := 1; i < data.Len(); i++ {  		for j := i; j > 0 && data.Less(j, j-1); j-- { -			data.Swap(j, j-1); +			data.Swap(j, j-1)  		}  	}  }  func IsSorted(data Interface) bool { -	n := data.Len(); +	n := data.Len()  	for i := n - 1; i > 0; i-- {  		if data.Less(i, i - 1) { -			return false; +			return false  		}  	} -	return true; +	return true  }  // Convenience types for common cases  type IntArray []int -func (p IntArray) Len() int            { return len(p); } -func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; } -func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; } +func (p IntArray) Len() int            { return len(p) } +func (p IntArray) Less(i, j int) bool  { return p[i] < p[j] } +func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i] }  type FloatArray []float -func (p FloatArray) Len() int            { return len(p); } -func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; } -func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; } +func (p FloatArray) Len() int            { return len(p) } +func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j] } +func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i] }  type StringArray []string -func (p StringArray) Len() int            { return len(p); } -func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; } -func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; } +func (p StringArray) Len() int            { return len(p) } +func (p StringArray) Less(i, j int) bool  { return p[i] < p[j] } +func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i] }  // Convenience wrappers for common cases -func SortInts(a []int)        { Sort(IntArray(a)); } -func SortFloats(a []float)    { Sort(FloatArray(a)); } -func SortStrings(a []string)  { Sort(StringArray(a)); } +func SortInts(a []int)        { Sort(IntArray(a)) } +func SortFloats(a []float)    { Sort(FloatArray(a)) } +func SortStrings(a []string)  { Sort(StringArray(a)) } -func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); } -func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); } -func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); } +func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)) } +func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)) } +func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } diff --git a/doc/progs/sortmain.go b/doc/progs/sortmain.go index 8f6b1061d..df2abc058 100644 --- a/doc/progs/sortmain.go +++ b/doc/progs/sortmain.go @@ -5,53 +5,53 @@  package main  import ( -	"fmt"; -	"sort"; +	"fmt" +	"sort"  )  func ints() { -	data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}; -	a := sort.IntArray(data); -	sort.Sort(a); +	data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586} +	a := sort.IntArray(data) +	sort.Sort(a)  	if !sort.IsSorted(a) {  		panic()  	}  }  func strings() { -	data := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}; -	a := sort.StringArray(data); -	sort.Sort(a); +	data := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"} +	a := sort.StringArray(data) +	sort.Sort(a)  	if !sort.IsSorted(a) {  		panic()  	}  }  type day struct { -	num        int; -	shortName  string; -	longName   string; +	num        int +	shortName  string +	longName   string  }  type dayArray struct { -	data []*day; +	data []*day  } -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) 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 days() { -	Sunday :=    day{ 0, "SUN", "Sunday" }; -	Monday :=    day{ 1, "MON", "Monday" }; -	Tuesday :=   day{ 2, "TUE", "Tuesday" }; -	Wednesday := day{ 3, "WED", "Wednesday" }; -	Thursday :=  day{ 4, "THU", "Thursday" }; -	Friday :=    day{ 5, "FRI", "Friday" }; -	Saturday :=  day{ 6, "SAT", "Saturday" }; -	data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday}; -	a := dayArray{data}; -	sort.Sort(&a); +	Sunday :=    day{ 0, "SUN", "Sunday" } +	Monday :=    day{ 1, "MON", "Monday" } +	Tuesday :=   day{ 2, "TUE", "Tuesday" } +	Wednesday := day{ 3, "WED", "Wednesday" } +	Thursday :=  day{ 4, "THU", "Thursday" } +	Friday :=    day{ 5, "FRI", "Friday" } +	Saturday :=  day{ 6, "SAT", "Saturday" } +	data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday} +	a := dayArray{data} +	sort.Sort(&a)  	if !sort.IsSorted(&a) {  		panic()  	} @@ -63,7 +63,7 @@ func days() {  func main() { -	ints(); -	strings(); -	days(); +	ints() +	strings() +	days()  } diff --git a/doc/progs/strings.go b/doc/progs/strings.go index 2c4937e38..0ec25f8e8 100644 --- a/doc/progs/strings.go +++ b/doc/progs/strings.go @@ -8,9 +8,9 @@ import "fmt"  import "os"  func main() { -	s := "hello"; +	s := "hello"  	if s[1] != 'e' { os.Exit(1) } -	s = "good bye"; -	var p *string = &s; -	*p = "ciao"; +	s = "good bye" +	var p *string = &s +	*p = "ciao"  } diff --git a/doc/progs/sum.go b/doc/progs/sum.go index f087ca3e5..74fd5bca3 100644 --- a/doc/progs/sum.go +++ b/doc/progs/sum.go @@ -7,7 +7,7 @@ package main  import "fmt"  func sum(a []int) int {   // returns an int -	s := 0; +	s := 0  	for i := 0; i < len(a); i++ {  		s += a[i]  	} @@ -16,6 +16,6 @@ func sum(a []int) int {   // returns an int  func main() { -	s := sum(&[3]int{1,2,3});  // a slice of the array is passed to sum -	fmt.Print(s, "\n"); +	s := sum(&[3]int{1,2,3})  // a slice of the array is passed to sum +	fmt.Print(s, "\n")  } | 
