Google GO (5) – "Effective Go" Notes

Effective GO link

“gofmt” could do the code formatting for you.

Underscore (_), is the blank identifier, provides a way to ignore values returned by a multi-valued expression.

x, _ = f() // ignore second value returned by f()

use range to help for loop

for _, value := range m { // key is unused
sum += value
}

In switch, cases can be presented in comma-seperated lists

switch c {
case ‘ ‘, ‘?’, ‘&’, ‘=’, ‘#’, ‘+’, ‘%’:
return true
}

Switch can be used to discover the dynamic type of an interface variable.

switch t := interfaceValue.(type) {
default:
fmt.Printf(“unexpected type %T”, type); // %T prints type
case bool:
fmt.Printf(“boolean %t\n”, t);
case int:
fmt.Printf(“integer %d\n”, t);
case *bool:
fmt.Printf(“pointer to boolean %t\n”, *t);
case *int:
fmt.Printf(“pointer to integer %d\n”, *t);
}

Functions support multiple returns, such as

func nextInt(b []byte, i int) (int, int)

Named return parameter is initialized by zero, and return by current value if return with no arguments.

Composite literal, could use

return &File{fd, name, nil, 0};

or labels inside

return &File{fd: fd, name: name}

new() returns the pointer with all zeroed memory.

make(T, args) creates slices, maps and channels.

Arrays, when it is passed to a function, it is a copy of the array, not just the pointer.

The size of an array is part of its type, which means [10]int and [20]int are distinct.

len(slice) -> length, cap(slice) -> capacity

In if statement, the expression may be preceded by a simple statement, which executes before the expression is evaluated.

if x := f(); x < y {

Go’s memory sharing design:

Do not communicate by sharing memory; instead, share memory by communicating.

Buffered channel & Unbuffered channel

ci := make(chan int); // unbuffered channel of integers
cj := make(chan int, 0); // unbuffered channel of integers
cs := make(chan *os.File, 100); // buffered channel of pointers to Files

Channels could be used as semaphore

var sem = make(chan int, MaxOutstanding)

func handle(r *Request) {
sem <- 1; // Wait for active queue to drain.
process(r); // May take a long time.
<-sem; // Done; enable next request to run.
}

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

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 }

Google GO (3)

原来还有个Tech Talk (pdf)。果然困了,半点都没看下去 o_O

不过如果GO如传说中编译的那么快的话,yy一下一分钟编译完firefox/OOo(当然要他们改用GO了)的场景,这样我一定没有借口不用Gentoo了。哈哈

letssseeee

Google GO (2)

果然是犯困了,刚才更新了env却跑到另一个term里执行…

skh-laptop/home/skh/temp
skh >>> 8g ./helloworld.go                                                                  09-11-12 2:41
skh-laptop/home/skh/temp
skh >>> 8l ./helloworld.8                                                                   09-11-12 2:41
skh-laptop/home/skh/temp
skh >>> ./8.out                                                                             09-11-12 2:41
Hello, 世界
skh-laptop/home/skh/temp
skh >>> ls -l 8.out                                                                         09-11-12 2:41
-rwxr-xr-x 1 skh skh 582423 2009-11-12 02:41 8.out*

这个hello world果然很大

Google GO

Google果然什么都开始搞了,昨儿推出了名为GO的新语言。今天睡觉前小看了一下GO的主页,还是很牛的。Design FAQ对GO的特性介绍的很清楚,GO的很多特性归结出来就是simple,code要simple,interpreter要simple,compiler要simple,debugger也要simple。

AUR上发现有人已经创建了go-lang的包了,于是安装了一下,编译过程果然如广告里介绍的一般,少于10s。不过尝试helloworld居然失败了,fmt package没找到。据说暂时还不支持dymanic linking,一个helloworld会超大,暂时没机会验证一下 =(

skh >>> 8g ./helloworld.go                                                                  09-11-12 2:28
./helloworld.go:3: fatal error: can’t find import: fmt

困死了,改天再看看吧。