Go のマップは Ruby でいうハッシュ、Python の辞書、要するに連想配列だ。
マップの宣言、初期化は例を見たほうが早いだろう。次のようにする。
package main import "fmt" func main() { var a map[string]int var b map[string]int = map[string]int{ "foo": 1, "bar": 2 } var c = map[string]int{ "hoge": 10, "fuga": 20 } fmt.Println(a) fmt.Println(b) fmt.Println(c) }
^o^ > go run map.go map[] map[foo:1 bar:2] map[hoge:10 fuga:20]
ここで注意。上の例の変数 a
のように宣言だけして初期化をしないと、nilマップというものになる。これは空のマップとは違って、キーの追加とかができない。試してみよう。
package main import "fmt" func main() { var a map[string]int fmt.Println(a) a["hoge"] = 100 fmt.Println(a) }
^o^ > go run map2.go map[] panic: assignment to entry in nil map goroutine 1 [running]: main.main() C:/Users/takatoh/Documents/w/learning-go/map2.go:10 +0xa7 exit status 2
この通り、a["hoge"] = 100
のところでエラーを起こしている。なんでこんな仕様になってるんだろ?
で、空のマップがほしい時には make
関数を使う。
package main import "fmt" func main() { var a = make(map[string]int) fmt.Println(a) a["foo"] = 10 a["bar"] = 20 fmt.Println(a) }
これなら新しいキー(と値)を追加できる。
^o^ > go run map3.go map[] map[foo:10 bar:20]
参照するには []
でキーを指定すればいいけど、返ってくる値は2つある。キーが存在する場合には対応する値と true
が、存在しない場合にはゼロ値と false
が返ってくる。これはつまり Go には多値があるってことだけど、これについては別の機会に書く。
ともかく、キーが存在するかどうかは2つ目の返り値を見ないとわからないので、ちょっと面倒。
あと、キー(と値)を削除するには delete
関数を使う。
package main import "fmt" func main() { a := map[string]int{ "foo": 1, "bar": 2 } fmt.Println(a) value, ok := a["foo"] if ok { fmt.Println(value) } a["baz"] = 3 delete(a, "bar") fmt.Println(a) }
^o^ > go run map4.go map[foo:1 bar:2] 1 map[baz:3 foo:1]