Google GO (4) – Tutorial Notes

Tutorial Notes

Three ways of declaration:

var s string = “”;
var s = “”;
s := “”;

For Loop(parentheses no needed, braces mandatory):

for i := 0; i < flag.NArg(); i++ {

To signal an erroneous return, call


Falling off main.main means “success”

Types are different even they are using the same bits. int and int32 are distinct, int and uint are distinct.

Strings are kinda const strings in C++, couldnt be changed.


var arrayOfInt [10]int;

Slice variable reference a segment of an array

a[low : high]

function func sum(a []int) int {} could be called in multiple ways

s := sum(&[3]int{1,2,3}); // a slice of the array is passed to sum
s := sum(&[…]int{1,2,3}); // want compiler to count the elements
s := sum([]int{1,2,3});


m := map[string]int{“one”:1 , “two”:2}


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


t := new(T);

For maps, slices and channels which have reference semantics, using make() instead

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

If a name (of a top-level type, function, method, constant or variable, or of a structure field or method) is capitalized, it is visible to the public, users of the package may see it. Otherwise, the name and hence the thing being named is visible only inside the package in which it is declared.

Open files

func Open(name string, mode int, perm int) (file *File, err os.Error)

Note there is a multi-value return here. err is nil if no error. Similarly, there are other methods for I/O

func (file *File) Close() os.Error
func (file *File) Read(b []byte) (ret int, err os.Error)
func (file *File) Write(b []byte) (ret int, err os.Error)
func (file *File) String() string

os.Error has a method called os.Error.String() could convert to a printing description.


switch nr, er := f.Read(&buf); true {
case nr < 0:

case nr == 0:

case nr > 0:


Interface is declared like

26 type reader interface {
27 Read(b []byte) (ret int, err os.Error);
28 String() string;
29 }

It is implemented by a type if the type implement *all* the methods declared in the interface. This means following empty interface is by default implemented by any type.

type Empty interface {}

Printf(), %v will print in a simple appropirate style by default. Print() and Println() would do the print fromatting automatically.

Type assertion, e.g. v.(Stringer) while Stringer is an interface, to see if v satisfies the Stringer interface.

s, ok := v.(Stringer); // Test whether v implements “String()”

Channel, a communications channel that connect two concurrent computations, using make() to create new channel.

09 // Send the sequence 2, 3, 4, … to channel ‘ch’.
10 func generate(ch chan int) {
11 for i := 2; ; i++ {
12 ch <- i // Send ‘i’ to channel ‘ch’.
13 }
14 }
16 // Copy the values from channel ‘in’ to channel ‘out’,
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’.
21 if i % prime != 0 {
22 out <- i // Send ‘i’ to channel ‘out’.
23 }
24 }
25 }

Go routines, starting the function running in parallel in the same address space

go sum(hugeArray); // calculate sum in the background

Then check the result by passing channel

ch := make(chan int);
go sum(hugeArray, ch);
// … do something else for a while
result := <-ch; // wait for, and retrieve, result

select statement choose which of the multiple communications listed can proceed

21 func server(op binOp, service chan *request, quit chan bool) {
22 for {
23 select {
24 case req := <-service:
25 go run(op, req); // don’t wait for it
26 case <-quit:
27 return;
28 }
29 }
30 }