From f340baa9492812622efdc18d7e84d9a1c09ef13b Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 13 Oct 2009 22:10:16 -0700 Subject: bye-bye to old makehtml. go can do the job just fine. R=rsc DELTA=290 (209 added, 13 deleted, 68 changed) OCL=35699 CL=35699 --- doc/go_tutorial.html | 63 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) (limited to 'doc/go_tutorial.html') diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html index f966ef936..27710ed26 100644 --- a/doc/go_tutorial.html +++ b/doc/go_tutorial.html @@ -1,15 +1,14 @@ -

Introduction

This document is a tutorial introduction to the basics of the Go systems programming language, intended for programmers familiar with C or C++. It is not a comprehensive guide to the language; at the moment the document closest to that is the -language specification. +language specification.

The presentation proceeds through a series of modest programs to illustrate key features of the language. All the programs work (at time of writing) and are -checked into the repository in the directory /doc/progs. +checked into the repository in the directory /doc/progs/.

Program snippets are annotated with the line number in the original file; for cleanliness, blank lines remain blank. @@ -45,8 +44,8 @@ The comment convention is the same as in C++:

     /* ... */
     // ...
-
 
+

Later we'll have much more to say about printing.

Echo

@@ -94,8 +93,8 @@ 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, even though they are needed as separators within a parenthesized list of declarations. @@ -128,8 +127,8 @@ The declaration statement has the form

     var s string = "";
-
 
+

This is the var keyword, followed by the name of the variable, followed by its type, followed by an equals sign and an initial value for the variable.

@@ -139,14 +138,14 @@ We could write

     var s = "";
-
 
+

or we could go even shorter and write the idiom

     s := "";
-
 
+

The := operator is used a lot in Go to represent an initializing declaration. (For those who know Sawzall, its := construct is the same, but notice that Go has no colon after the name in a full var declaration. @@ -177,8 +176,8 @@ It's defined that way. Falling off the end of main.main means

     os.Exit(1)
-
 
+

The os package contains other essentials for getting started; for instance, os.Args is an array used by the flag package to access the command-line arguments. @@ -213,8 +212,8 @@ a string value:

     s[0] = 'x';
     (*p)[1] = 'y';
-
 
+

In C++ terms, Go strings are a bit like const strings, while pointers to strings are analogous to const string references.

@@ -225,8 +224,8 @@ Arrays are declared like this:

     var array_of_int [10]int;
-
 
+

Arrays, like strings, are values, but they are mutable. This differs from C, in which array_of_int would be usable as a pointer to int. In Go, since arrays are values, it's meaningful (and useful) to talk @@ -286,21 +285,21 @@ elements for you, use ... as the array size:

     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:

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

There are also maps, which you can initialize like this:

     m := map[string] int {"one":1 , "two":2}
-
 
+

The built-in function len(), which returns number of elements, makes its first appearance in sum. It works on strings, arrays, slices, and maps. @@ -317,14 +316,14 @@ returns a pointer to the allocated storage.

     type T struct { a, b int }
     var t *T = new(T);
-
 
+

or the more idiomatic

     t := new(T);
-
 
+

Some types - maps, slices, and channels (see below) - have reference semantics. If you're holding a slice or a map and you modify its contents, other variables referencing the same underlying data will see the modification. For these three @@ -332,15 +331,15 @@ types you want to use the built-in function make():

     m := make(map[string] int);
-
 
+

This statement initializes a new map ready to store entries. If you just declare the map, as in

     var m map[string] int;
-
 
+

it creates a nil reference that cannot hold anything. To use the map, you must first initialize the reference using make() or by assignment to an existing map. @@ -360,8 +359,8 @@ too little precision to represent the value.

     const hard_eight = (1 << 100) >> 97  // legal
-
 
+

There are nuances that deserve redirection to the legalese of the language specification but here are some illustrative examples:

@@ -373,8 +372,8 @@ language specification but here are some illustrative examples: x := 1.5 // a float i3div2 := 3/2 // integer division - result is 1 f3div2 := 3./2. // floating point division - result is 1.5 - +

Conversions only work for simple cases such as converting ints of one sign or size to another, and between ints and floats, plus a few other simple cases. There are no automatic numeric conversions of any kind in Go, @@ -446,8 +445,8 @@ object. We could write n.fd = fd; n.name = name; return n - +

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

@@ -585,8 +584,8 @@ Finally we can run the program: hello, world can't open file; err=No such file or directory % - +

Rotting cats

Building on the file package, here's a simple version of the Unix utility cat(1), @@ -864,8 +863,8 @@ Within the fmt package, Printf is declared with this s

     Printf(format string, v ...) (n int, errno os.Error)
-
 
+

That ... represents the variadic argument list that in C would be handled using the stdarg.h macros, but in Go is passed using an empty interface variable (interface {}) that is then unpacked @@ -888,8 +887,8 @@ prints

     18446744073709551615 -1
-
 
+

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

@@ -904,8 +903,8 @@ is

     18446744073709551615 {77 Sunset Strip} [1 2 3 4]
-
 
+

You can drop the formatting altogether if you use Print or Println instead of Printf. Those routines do fully automatic formatting. The Print function just prints its elements out using the equivalent @@ -946,8 +945,8 @@ default formatter for that type will use it and produce the output

     77 Sunset Strip
-
 
+

Observe that the String() method calls Sprint (the obvious Go variant that returns a string) to do its formatting; special formatters can use the fmt library recursively. @@ -970,15 +969,17 @@ Schematically, given a value v, it does this: type Stringer interface { String() string } - + +

+

     s, ok := v.(Stringer);  // Test whether v implements "String()"
     if ok {
         result = s.String()
     } else {
         result = default_output(v)
     }
-
 
+

The code uses a ``type assertion'' (v.(Stringer)) to test if the value stored in v satisfies the Stringer interface; if it does, s will become an interface variable implementing the method and ok will @@ -1000,8 +1001,8 @@ interface type defined in the io library: type Writer interface { Write(p []byte) (n int, err os.Error); } - +

(This interface is another conventional name, this time for Write; there are also io.Reader, io.ReadWriter, and so on.) Thus you can call Fprintf on any type that implements a standard Write() @@ -1081,8 +1082,8 @@ computation but in the same address space:

     go sum(huge_array); // calculate sum in the background
-
 
+

If you want to know when the calculation is done, pass a channel on which it can report back:

@@ -1091,8 +1092,8 @@ on which it can report back: go sum(huge_array, ch); // ... do something else for a while result := <-ch; // wait for, and retrieve, result - +

Back to our prime sieve. Here's how the sieve pipeline is stitched together:

-- cgit v1.2.3