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]