Go についてのメモ
package main import "fmt" import "reflect" type Arr [5]int func main() { a := Arr{1, 2, 3} //配列 b := Arr{7, 8, 9} //配列 c := append(a[:], b[:]...) //append の引数にはスライスしか取らない fmt.Println(c) fmt.Println(reflect.ValueOf(c).Kind()) } //=>[1 2 3 0 0 7 8 9 0 0] //=>slice
package main import "fmt" func main() { a := [6]int{1, 2, 3, 4, 5, 6} b := a[1:3] fmt.Println(b) //=>[2 3] b = b[0:5] fmt.Println(b) //=>[2 3 4 5 6] }
変数に nil は代入できない。
func main() { var a int a = nil fmt.Println(a) }
はコンパイル・エラー。
こういうことは可能。type A struct の中に A を使っているが、*A はポインタなので構造体の再帰的定義(エラーになる)にならない。
package main import "fmt" type A struct { value string parent *A } func main() { oya := &A{"のらの親", &A{}} nora := &A{"のら", oya} konora := &A{"子のら", nora} for a := konora; (*a).parent != nil; a = (*a).parent { fmt.Println((*a).value) } } //(*a) はすべて a と省略して書ける
実行。親を遡っていく。
$ go run a.go 子のら のら のらの親
例えばサブルーチンでカウントする。このとき、構造体は値渡しなので、以下は期待した動作をしない。
package main import "fmt" type A struct { value int } func count(n A) { n.value++ } func main() { x := A{value: 1} count(x) fmt.Println(x.value) //=>1 }
正しくは構造体のポインタを渡さないといけない。
package main import "fmt" type A struct { value int } func count(n *A) { n.value++ //(*n).value++のシンタックスシュガー } func main() { x := &A{value: 1} count(x) fmt.Println(x.value) //=>2 }
代入の場合も同様。y := x の代入時にコピーされる。
package main import "fmt" type A struct { value int } func main() { x := A{value: 1} y := x y.value++ fmt.Println(y.value) //=>2 fmt.Println(x.value) //=>1 }
Go は基本的に破壊的変更をしづらいようになっているのだな。破壊的変更はポインタでやる。ただし、もちろん参照型は別。