Go のマップの基本(宣言・初期化・追加・削除)

マップはキーと値のペアを格納するデータ構造だ。他の言語では「辞書」や「ハッシュテーブル」と呼ばれることもある。

マップの宣言と初期化

マップを作る方法は主に2つある。

// make を使う
ages := make(map[string]int)

// リテラルで初期化
ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
}

map[キーの型]値の型 という形式で型を指定する。make を使った場合は空のマップが作られる。

要素の追加と取得

ages := make(map[string]int)

// 追加
ages["Alice"] = 30
ages["Bob"] = 25

// 取得
fmt.Println(ages["Alice"]) // 30

存在しないキーを取得すると、値の型のゼロ値が返る。

fmt.Println(ages["Charlie"]) // 0(int のゼロ値)

要素の削除

delete 関数でキーを指定して削除する。

delete(ages, "Bob")
fmt.Println(ages) // map[Alice:30]

存在しないキーを削除しても panic は起きない。何も起こらないだけだ。

マップの長さ

len 関数で要素数を取得できる。

ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
}
fmt.Println(len(ages)) // 2

var で宣言した場合

var で宣言しただけのマップは nil になる。

var ages map[string]int
fmt.Println(ages == nil) // true

nil マップは読み取りはできるが、書き込みは panic になる。

var ages map[string]int
fmt.Println(ages["Alice"]) // 0(読み取りはOK)
ages["Alice"] = 30         // panic: assignment to entry in nil map

マップを使う前に make で初期化するか、リテラルで宣言する習慣をつけよう。

様々な型をキーや値に使う

キーには比較可能な型(==で比較できる型)が使える。

// int をキーに
scores := map[int]string{
    1: "Gold",
    2: "Silver",
    3: "Bronze",
}

// 構造体をキーに
type Point struct {
    X, Y int
}
visited := map[Point]bool{
    {0, 0}: true,
    {1, 2}: true,
}

スライス、マップ、関数はキーにできない。これらは比較不可能な型だからだ。