技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

map【Go】

宣言と代入

宣言と同時に代入する方法は下記の通りになります。

a := map[string]int {
  "usa" : 1
  "china": 2 
}

[ ]で指定するのが、keyの型、[ ]の後に指定するのがvalueの型です。

宣言

代入せずに、map変数を宣言するには、makeを使用します。

b := make(map[string]int, 1)
b["japan"] = 3


map変数の宣言時には、型宣言だけをしてはいけません。型の末尾に「{}」をつけるかmakeを使って初期化しないと、nilとなってしまい、参照などした時に assignment to entry in nil mapエラーが発生するので注意が必要です。

var b map[string]int
b["japan"] = 3    // エラー


しかし、エントリ数がわかっている場合は、型の末尾に「{}」をつけた宣言方法ではなく、 makeによる容量を指定した宣言を用いるべきです。 代入時に無駄な拡張コストがかかるからです。

b := map[string]int{}    // エントリ数がわかっている場合には、好ましくない宣言方法
b["japan"] = 3


エントリの確認

keyを使ってアクセスすると、2つの返り値を得る事ができます。
valueとokです。okは、そのkeyが存在するかどうかをbool値で返します。

k, ok := a["japan"]    // okは変数名なので任意の名前でよい
fmt.Println(k, ok)    // 3, true

okを取得しないこともできます。

k := a["japan"]
fmt.Println(k)    // 3

さらに、存在しているかどうかチェックしたいときは、下記のようにもできます。

_, ok := a["japan"]    // アンダースコアで返り値としてのvalueを破棄する
fmt.Println(ok)    // true


エントリの削除

組み込み関数deleteを使います。

delete(a, "banana")


スライスとmapのアクセス速度

対象のインデックスが自明な場合、またはloop処理などで順にアクセスする場合にはスライスに分があります。
反対に、インデックスがわからず探索する必要がある場合には、mapを用いた方が処理が速くなります。


参考

qiita.com

cipepser.hatenablog.com