Google GO (4) – 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
os.Exit(1)
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.
Arrays
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});
Maps
m := map[string]int{“one”:1 , “two”:2}
Allocation
type T struct { a, b int }
var t *T = new(T);
or
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
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 }
15
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 }