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]