A Tour of Go - More types : 自分用リファレンスメモ

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

Pointers

ポインタ型の宣言

//宣言
var po *int

&オペレータでポインタを引き出せる。

*オペレータでポインタの指す先の変数を示す。

i := 42
//宣言 & 初期化
p := &i
fmt.Println(p) // 0x40e020
fmt.Println(*p) //42

//ポインタpを通してiへ値を代入する
*p = 21
fmt.Println(*p) //21
fmt.Println(i) //21

Struct

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v.X)

    v2 := Vertex{X: 1}  // Y:0 is implicit
}
Pointers to structs

フィールドには、structのポインタを通してアクセスすることもできる。

structのポインタpが指すフィールドXにアクセスするには(*p).Xと書く変わりにp.Xと書くことができる。

func main() {
    v := Vertex{1, 2}
    p := &v
    p.X = 1e9
    fmt.Println(v) //{1000000000 2}
    fmt.Println(p) //&{1000000000 2}
    fmt.Println(*p) //{1000000000 2}
    fmt.Println(p.X) //1000000000
    fmt.Println((*p).X) //1000000000
}

Arrays

宣言と初期化

//宣言
var a [10]int
//宣言 & 初期化
primes := [6]int{2, 3, 5, 7, 11, 13}
Slices

a[low : high]で取り出せる。

最初の要素を含み、最後の要素は省かれる。

スライスは配列への参照なので、値を変更すると取り出し元の値も変更される。

func main() {
    primes := [6]int{2, 3, 5, 7, 11, 13}
    var s []int = primes[1:4]
        // [3 5 7]
    fmt.Println(s)
    s[0] = 100
         // [2 100 5 7 11 13]
    fmt.Println(primes)
}
Slice defaults

上限または下限を省略することができる。

var a [10]int
a[0:10]
a[:10]
a[0:]
a[:]
Creating a slice with make

動的サイズの配列作成。make()を使用する。

func main() {
    // a len=5 cap=5 [0 0 0 0 0]
    a := make([]int, 5)
    printSlice("a", a)

    // b len=0 cap=5 []
    b := make([]int, 0, 5)
    printSlice("b", b)

    // c len=2 cap=5 [0 0]
    c := b[:2]
    printSlice("c", c)

    // d len=3 cap=3 [0 0 0]
    d := c[2:5]
    printSlice("d", d)
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}
Appending to a slice

スライスへの要素の追加はappend()を使用する。

func main() {
    var s []int
    // len=0 cap=0 []
    printSlice(s)

    // len=1 cap=2 [0]
    s = append(s, 0)
    printSlice(s)

    // len=2 cap=2 [0 1]
    s = append(s, 1)
    printSlice(s)

    // len=5 cap=8 [0 1 2 3 4]
    s = append(s, 2, 3, 4)
    printSlice(s)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
range

スライスをforループ等でiterateするにはrangeを使用する。

戻り値はindexとvalue。必要な戻り値は_(アンダーバー)で捨てることができる。

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
    fmt.Printf("2**%d = %d\n", i, v)
}

for _, value := range pow {
    fmt.Printf("%d\n", value)
}
Maps

キーと値とを関連付。キーをString型にすることで他言語のhash, dictionaryのような使い方ができる。

以下の例は2次元座標のstructを持つMap[string]の定義。

宣言しただけではアクセスできず、 make()で初期化する必要がある模様。

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"])

    // 宣言 & 初期化
    var m2 = map[string]Vertex{
        "Bell Labs": Vertex{
            40.68433, -74.39967,
        },
    }
    fmt.Println(m2["Bell Labs"]
}
Mutating Maps

mapの操作。

要素の追加、更新

m[key] = elem

要素の取得

elem = m[key]

要素の削除

delete(m, key)

キーの存在確認。キーが存在しない場合、okにfalseが返ってくる。

elem, ok := m[key]

Function values

関数オブジェクトを取得

hypot := func(x, y float64) float64 {
    return math.Sqrt(x*x + y*y)
}

引数に関数型を定義

func compute(fn func(float64, float64) float64) float64 {
    return fn(3, 4)
}
fmt.Println(compute(hypot))