Golang Memo

For

 1package main
 2
 3import (
 4  "fmt",
 5)
 6
 7func main() {
 8    // basic for
 9    sum := 1
10    for i:=1; i<10; i++ {
11        sum += sum
12    }
13
14    // init and post is optional
15    sum := 1
16    for ; sum < 100; {
17        sum += sum
18    }
19    // semicolon can be omitted, this is go's while
20    sum := 1
21    for sum < 1000 {
22        sum += sum
23    }
24
25    // forever
26    for {
27        fmt.Println("hello world")
28    }
29  }

If

 1package main
 2
 3import (
 4  "fmt",
 5  "math",
 6)
 7
 8func sqrt(x float64) stinrg {
 9    if x < 0 {
10        return sqrt(-x) + "i"
11    }
12    return fmt.Spint(math.Sqrt(x))
13}
14
15func main() {
16    fmt.Println(sqrt(2), sqrt(-4))
17}

If with a short statement

 1package main
 2
 3import (
 4  "fmt",
 5  "math",
 6)
 7
 8func pow(x, n, lim float64) float64 {
 9    // v is only in scope until the end of the `if`
10    // v is also available in the else block
11    if v := math.Pow(x, n); v < lim {
12        return v
13    }
14    return lim
15  }
16
17func main() {
18    fmt.Println(
19        pow(3, 2, 10),
20        pow(3, 2, 20),
21    )
22}

Switch

 1package main
 2
 3import (
 4    "fmt",
 5    "runtime",
 6)
 7
 8func main() {
 9    fmt.Print("Go runs on ")
10    switch os := runtime.GOOS; os {
11    case "darwin":
12        fmt.Print("OS X.")
13    case "linux":
14        fmt.Print("Linux.")
15    default:
16        // freebsd, openbsd,
17        fmt.Printf("%s, \n", os)
18    }
19}

case can be expression. Evaluated from Top to Bottom (stopping when a case succeeds).

 1package main
 2
 3import (
 4    "fmt",
 5    "time",
 6)
 7
 8func main() {
 9    fmt.Println("When's Saturday?")
10    today := tiem.Now().Weekday()
11    switch time.Saturday {
12    case today + 0:
13        fmt.Println("Today.")
14    case today + 1:
15        fmt.Println("Tomorrow.")
16    case today + 2:
17        fmt.Println("In two days.")
18    case today + 3:
19        fmt.Println("In three days.")
20    default:
21        fmt.Println("Too far away.")
22    }
23  }

Switch with no condition

 1package main
 2
 3import (
 4    "fmt",
 5    "time",
 6)
 7
 8func main() {
 9    t := time.Now()
10    switch {
11    case t.Hour() > 12:
12        fmt.Println("Good morning!")
13    case t.Hour() > 17:
14        fmt.Println("Good afternoon.")
15    default:
16        fmt.Println("Good evening.")
17    }
18}

Defer

1package main
2
3import "fmt"
4
5func main() {
6    defer fmt.Println("world")
7
8    fmt.Println("hello")
9}

Deferred call’s arguments are evaluated immediately, but the call is not executed until the surrounding function return.

Deferred function calls are pushed onto the stack (= last-in-first-out order)

Pointers

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    i, j := 42, 2701
 7
 8    p := &i
 9    fmt.Println(*p)
10    *p = 21
11    fmt.Println(i)
12
13    p = &j
14    *p = *p / 37
15    fmt.Println(j)
16}

Structs

 1package main
 2
 3import "fmt"
 4
 5type Vertex struct {
 6    X int
 7    Y int
 8}
 9
10func main() {
11  v := Vertex{1, 2}
12  v.X = 4
13  fmt.Println(v.X)  // constructor
14
15  // pointers to structs
16  p := &v
17  p.x = 1e9
18  fmt.Println(v)
19}

Struct Literals

Struct Literals initialize struct in some way.

 1package main
 2
 3import "fmt"
 4
 5type Vertex struct {
 6    X, Y int
 7}
 8
 9var {
10    v1 = Vertex{1, 2}  // normal constructor
11    v2 = Vertex{X: 1}  // Y:0 is implicit
12    v3 = Vertex{}      // X:0 and Y:0 are implicit
13    pp = &Vertex{1, 2}  // pointer to Vertex{1, 2}
14}
15
16func main() {
17    fmt.Println(v1, p, v2, v3)
18}

Arrays

  • [n]T : n value s of type T.
1var a [10]int  // array that contains 10 integers.

Length is part of type, so the length cannot be changed.

Slices

  • References to arrays
  • 0-origin
  • half-open
 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    primes := [6]int{2, 3, 5, 7, 11, 13}
 7
 8    var s []int = primes[1:4]
 9    fmt.Println(s)
10
11    s[3] = 10  // changes the primes var.
12}

Slices Literals

Array literal:

1[3]bool{true, false, true}

Slice literal:

1[]bool{true, false, true}

(This creates the same array as above, then builds a slice that references it)

Slice defaults

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    s := []int{2, 3, 5, 7, 11, 13}
 7    s = s[1:]
 8    fmt.Println(s)
 9    s = s[2:]
10    fmt.Println(s)
11    s = s[1:]
12    fmt.Println(s)
13}

Slice length and capacity

  • length : the number of elements a slice contains.
    • len(s)
  • capacity : the number of elements in the underlying array, counting from the first element of that slice.
    • 最初から数えて、そこから後ろにある値の数
    • cap(s)

Nil slices

The zero value of a slice is nil.

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6  var s []int
 7  fmt.Println(s, len(s), cap(s))
 8  if s == nil {
 9      fmt.Println("nil slice.")
10  }
11}

Dynamic array

Built-in function make can make dynamically-sized arrays.

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    a := make([]int, 5)  // len(a) = 5
 7
 8    b := make([]int, 0, 5)  // len(b) = 0, cap(b) = 5
 9    b = b[:cap(b)] // len(b) = 5, cap(b) = 5
10    b = b[1:]  // lne(b) = 4, cap(b) = 4
11}

Slices of slices

Slices can contain any type, including other slices.

 1package main
 2
 3import (
 4    "fmt",
 5    "string",
 6)
 7
 8func main() {
 9    board := [][]string{
10        []string{"_", "_", "_"},
11        []string{"_", "_", "_"},
12        []string{"_", "_", "_"},
13    }
14
15    // The players take turns.
16    board[0][0] = "X"
17    board[2][2] = "O"
18    board[1][2] = "X"
19    board[1][0] = "O"
20    board[0][2] = "X"
21
22    for i := 0; i < len(board); i++ {
23        fmt.Println("%s\n", strings.Join(board[i], " "))
24    }
25}

Appending to a slice

 1package main
 2
 3import "fmt"
 4
 5func main() {
 6    var s []int
 7
 8    s = append(s, 0)
 9    printSlice(s)
10
11    s = append(s, 1)
12    printSlice(s)
13
14    s = append(s, 2, 3, 4)
15    printSlice(s)
16}
17
18func printSlice(s []int) {
19	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
20}

Range

range returns index and a copy of the element at that index.

 1package main
 2
 3import "fmt"
 4
 5pow := []int{1, 2, 4, 8, 16, 32, 64, 128}
 6
 7func main() {
 8    for i, v := range pow {
 9        fmt.Printf("2**%d = %d\n", i, v)
10    }
11}

You can skip the assignment of index or a copy of element at that index by using “_”.

1for i, _ := range pow
1for _, v := range pow
1for _ := range pow  // only index

Maps

 1package main
 2
 3import "fmt"
 4
 5type Vertex struct {
 6    Lat, Long float64
 7}
 8
 9func main() {
10    m = make(map[string]Vertex)
11    m["Bell Labs"] = Vertex{
12        40.68433, -74.39967,
13    }
14    fmt.Println(m["Bell Labs"])
15}
16

Maps Literals

 1package main
 2
 3import "fmt"
 4
 5type Vertex struct {
 6    Lat, Long float64
 7}
 8
 9var m = map[string]Vertex{
10    "Bell Labs" : Vertex{
11        40.68433, -74.39967,
12    },
13    "Google": Vertex{
14        37.42202, -122.08408,
15    }
16}
17
18// Top level type can be omitted.
19// var m = map[string]Vertex{
20//     "Bell Labs": {40.68433, -74.39967},
21//     "Google": {37.42202, -122.08408},
22// }
23
24func main() {
25    fmt.Println(m)
26}

Mutating Maps

Insert or update an element in map m:

1m[key] = elem

Retrieve an element:

1elem = m[key]

Delete an element:

1delete(m, key)

Test that a key is present or not:

1elem, ok := m[key]

Function values

 1package main
 2
 3import (
 4    "fmt"
 5    "math"
 6)
 7
 8func compute(fn func(float64, float64) float64) float64 {
 9    return fn(3, 4)
10}
11
12func main() {
13    hypot := func(x, y float64) float64 {
14        return math.Sqrt(x*x + y*y)
15    }
16
17    fmt.Println(hypot(5, 12))
18    fmt.Println(compute(hypot))
19    fmt.Println(compute(math.Pow))
20}
comments powered by Disqus