マッ

マップ の Go

2個の演習

マップについて

Goでは、mapはハッシュテーブルを表す組み込みのデータ型です。 他のプログラミング言語では、mapはdictや連想配列、キーと値のストアとして知られているかもしれません。 こうした概念に馴染みがなければ、mapは辞書のようなものだと考えてみてください。辞書では、各単語がkeyで、その定義がmapのelementにあたります。

始める前に、mapについてさらに深く掘り下げるために、mapのGo仕様とmapのGoブログを紹介しておきます。

構文的には、mapは次のようになります。

map[KeyType]ElementType

KeyTypeは比較可能な型である必要がありますが、ElementTypeはGoで有効な任意の型にできます。つまり、プリミティブな変数からスライスまで、どんなものでも格納できます。

Goのmapは順序を持たないことを覚えておくことが大切です。mapをループして要素を出力しようとすると、要素がランダムな順序で出力されるのを見て驚くかもしれません(よければ試してみてください)。

また、各キーは一意であることも重要です。同じキーを2回代入すると、対応するキーの値が上書きされます。

mapは参照型です。つまり、mapを渡してもGoはmap全体をコピーしません。 代わりにGoが行うのは、mapのポインターのコピーです。これにより、mapを関数や変数に渡すのが低コストになります。 初期化されていないmapの値はnilです。

mapは次のように定義できます(これはnil mapとも呼ばれます)。

  var foo map[string]int

mapを初期化するには、次のようにします。

  // With map literal
  foo := map[string]int{}

または

  // or with make function
  foo := make(map[string]int)

nil mapは初期化されたmapとは異なります。nil mapに書き込むと、ランタイムエラーが発生します。

panic: assignment to entry in nil map

そのため、使う前にmapを初期化することが大切です

mapでできる操作をいくつか紹介します。

  // Add a value in a map with the `=` operator:
  foo["bar"] = 42
  // Here we update the element of `bar`
  foo["bar"] = 73
  // To retrieve a map value, you can use
  baz := foo["bar"]
  // To delete an item from a map, you can use
  delete(foo, "bar")

mapに存在しないキーの値を取得しようとすると、値の型のゼロ値が返されます。 これは、ElementTypeのデフォルト値(たとえばintなら0)が有効な値である場合に、特に混乱を招くかもしれません。 mapにキーが存在するかどうかを確認するには、次のようにします。

  value, exists := foo["baz"]
  // If the key "baz" does not exist,
  // value: 0; exists: false

これまで見てきたように、mapが初期化されているかどうかを判別するのは簡単で、単純にnilと比較すればよいのですが、他のmap同士ではどうでしょうか? mapは比較可能ではないので==演算子は使えませんが、reflectパッケージに助けがあります。それはDeepEqualと呼ばれるもので、次のように使えます。

import "reflect"

// ....

equal := reflect.DeepEqual(map[string]int{}, map[string]int{})
fmt.Println(equal)
// Output: true

でも待ってください。mapが比較可能でないのなら、なぜnilとは比較できるのでしょうか? 仕様がこれについて例外を設けています。比較可能の仕様をご覧ください。

最後に、複数のゴルーチンからmapに書き込もうとすると、レース検出器が作動します。GoのドキュメントとGoブログをご覧ください。 別の方法として、この問題を回避するためにsync.Mapやatomic、mutexを使うこともできます。

GitHubで編集 リンクは新しいウィンドウまたはタブで開きます

マップを学習する

練習はロックされています

マップを練習するには、あと3個の演習のロックを解除してください