go lang tutorial

Click here to load reader

Post on 19-Aug-2014

5.501 views

Category:

Education

2 download

Embed Size (px)

DESCRIPTION

這是 Code & Beer Meetup 的第一次 Talk 投影片,主題為 Go Lang 的 Tutorial。

TRANSCRIPT

  • Go Lang Tutorial Wei-Ning Huang (AZ)
  • About the Speaker Wei-Ning Huang (a.k.a: AZ) Open source / Freelance Developer Found out more at http://azhuang.me
  • About the Slide License: Most of the code examples come from official Go Tour and Effective Go
  • Outline History Why Go? Library Support Tutorial Variable Declaration Function Declaration Flow Control Method and Interface Goroutines Conclusion References
  • Go!
  • History From Google! The guys at Plan 9 from Bell Labs Current Version 1.1.2, still being actively developed
  • Why Go! Fast Almost as fast as C Faster than C in some cases A small language Statically-typed Garbage Collection Easy to write/learn Reflection
  • How fast is Go? From Computer Language Benchmark Game
  • Who use Go? Google, of course Google App Engine also supports Go!
  • Library Support A lot of built-in support including: Containers: container/heap, container/list Web server: net/http Cryptography: crypto/md5, crypto/sha1 Compression: compress/gzip Database: database/sql
  • Third-Party Libraries Gorilla: Web Framework go-qt: Qt binding for Go go-gtk3: Gtk3 binding for Go go-opengl: OpenGL binding for Go go:ngine: Go 3D Engine mgo: MongoDB binding for go Tons more at: https://code.google.com/p/go-wiki/wiki/Projects
  • Hello World! package main import "fmt" func main() { fmt.Println("Hello, ") } $ go run hello_word.go Hello,
  • Using Package package main import ( "fmt" "math/rand" ) func main() { fmt.Println("My favorite number is", rand.Intn(10)) } You can also import package with separated line import "fmt" import "math/rand"
  • In Go, a name is exported if it begins with capital letter. That is, you should use instead of Exported Names fmt.Println("My favorite number is", rand. Intn(10)) fmt.println("My favorite number is", rand. Intn(10))
  • Variables package main import "fmt" var x, y, z int func main() { var c, python, java = true, false, "no!" haskell, racket, sml := true, true, false fmt.Println(x, y, z, c, python, java, haskell, racket, sml) } type can be omitted, since compiler can guess it from the initializer using the := construct, we can omit the var keyword and type!
  • Basic Types bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // alias for uint8 rune // alias for int32 // represents a Unicode code point float32 float64 complex64 complex128 var c complex128 = 1 + 2i
  • Constants package main import "fmt" const Pi = 3.14 func main() { const World = "" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) }
  • Grouping Variable and Constants var ( ToBe bool = false MaxInt uint64 = 1 1 { fmt.Println("if true") } if b := 123 * 456; b < 10000 { fmt.Println("another one, but with short statement") } } short statement, b is lives only inside if block
  • Condition: Switch func main() { fmt.Print("Go runs on ") switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") case "linux": fmt.Println("Linux.") default: // freebsd, openbsd, // plan9, windows... fmt.Printf("%s.", os) } } Just like if, can have short statement Switch cases evaluate cases from top to bottom, stopping when a case succeeds.
  • Switch Without Condition func main() { t := time.Now() switch { case t.Hour() < 12: fmt.Println("Good morning!") case t.Hour() < 17: fmt.Println("Good afternoon.") default: fmt.Println("Good evening.") } } Like writing long if/else chains no condition
  • Structs package main import "fmt" type Vertex struct { X int Y int } func main() { v := Vertex{1, 2} v.X = 4 fmt.Println(v.X) } A struct is a collection of fields. Struct fields are accessed using a dot.
  • Structs package main import "fmt" type Vertex struct { X int Y int } func main() { v := Vertex{1, 2} v.X = 4 p := &v fmt.Println(v.X, p.X) } p is a pointer to v, which has type *Vertex Use dot to access field of a pointer
  • The new Function package main import "fmt" type Vertex struct { X, Y int } func main() { v := new(Vertex) fmt.Println(v) v.X, v.Y = 11, 9 fmt.Println(v) } The expression new(T) allocates a zeroed T value and returns a pointer to it. v has type: *Vertex
  • Slices func main() { p := []int{2, 3, 5, 7, 11, 13} fmt.Println("p ==", p) fmt.Println("p[1:4] ==", p[1:4]) // [3 5 7] fmt.Println("p[:3] ==", p[:3]) // [2 3 5] fmt.Println("p[4:] ==", p[4:]) // [11 13] for i := 0; i < len(p); i++ { fmt.Printf("p[%d] == %dn", i, p[i]) } var z []int if z == nil { fmt.Println("nil value") } } A slice points to an array of values and also includes a length. The zero value of a slice is nil empty slice: nil
  • Making Slices func main() { a := make([]int, 5) printSlice("a", a) b := make([]int, 0, 5) printSlice("b", b) } func printSlice(s string, x []int) { fmt.Printf("%s len=%d cap=%d %vn", s, len(x), cap(x), x) } Use the make function to create slices. make(type, length, capacity) a len=5 cap=5 [0 0 0 0 0] b len=0 cap=5 []
  • Array V.S. Slices func main() { var array = [...]string{"a", "b", "c"} var slice = []string{"a", "b", "c"} fmt.Printf("%Tn", array) fmt.Printf("%Tn", slice) //array = append(array, array...) // Won't compile! slice = append(slice, slice...) fmt.Println(slice) } [3]string []string [a b c a b c]
  • Maps import "fmt" type Vertex struct { Lat, Long float64 } var m map[string]Vertex func main() { m = make(map[string]Vertex) m["Bell Labs"] = Vertex{ 40.68433, -74.39967, } fmt.Println(m["Bell Labs"]) } A map maps keys to values. Maps must be created with make (not new) before use; the nil map is empty and cannot be assigned to.
  • Maps Literals var m = map[string]Vertex{ "Bell Labs": Vertex{ 40.68433, -74.39967, }, "Google": Vertex{ 37.42202, -122.08408, }, } var m2 = map[string]Vertex{ "Bell Labs": {40.68433, -74.39967}, "Google": {37.42202, -122.08408} } map[key_type]value_type{ key1: value1, key2: value2 } Can omit type name
  • Mutating Maps m := make(map[string]int) m["Answer"] = 42 Assigning m, ok := m["Answer"] if ok { fmt.Println("key exists!") } Testing if a key exists delete(m, "Answer") Deleting an element
  • Iterating through Slices or Maps package main import "fmt" var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} var m = map[string]int{"a": 1, "b": 2} func main() { for i, v := range pow { fmt.Printf("2**%d = %dn", i, v) } for k, v := range m { fmt.Printf("%s: %dn", k, v) } } Use the range keyword
  • The _ Variable package main import "fmt" var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} var m = map[string]int{"a": 1, "b": 2} func main() { for _, v := range pow { fmt.Printf("%dn", v) } for _, v := range m { fmt.Printf("%dn", v) } } Go wont let you compile you declare some variable but didnt use it. In this case, you can assign it to _ to indicate that it will not be used. We dont use index here, assign it to _. We dont use key here, assign it to _.
  • Go: Objects without Class No class, use interfaces instead No inheritance, use embedding instead
  • Method Declaration type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) } Basically look like functions, but with extra receiver declaration before function name.
  • Method Declaration (contd) func (t time.Time) bla() string { return t.LocalTime().String()[0:5] } You may be tempted to declare new method on existing type, like monkey patching in Python or Ruby. cannot define new methods on non-local type time. Time type MyTime time.Time func (t MyTime) bla() string { return t.LocalTime().String()[0:5] } The correct way is to create a type synonym then define method on it.
  • Interfaces type Abser interface { Abs() float64 } type MyFloat float64 func (f MyFl