Go言語:Map

Mapの話

  • mapの型の指定は、キーと値の型をそれぞれ指定する。
    • map[キーの型]値の型という形式。
    • map[string]int みたいな。
  • 作成するには、make関数、もしくは初期化子を使う。
    • make関数、空の初期化子で作ったmapは、空。
    • 初期化前のmapは、nil
  • nilのmapに要素を割り当てられない。
    • panic: assignment to entry in nil mapになる。
  • 初期化時には、必ずキーが必要。
    • structのフィールドを明示する方法に同じ。
  • 初期化したmapの値は、指定された型のzero valueが与えられる。
  • ブラケットとキー[キー]でアクセス可能。
    • キーと値を削除するには、delete関数を使用する。
  • ブラケットでキーにアクセスした返り値の2つ目は、キーが存在するかどうかのbool値を返す。
    • キーが存在しない場合にfalse

試してみた1

mapの操作

withNilMap
map[]
0
true
withMakeMap
map[]
0
withEmptyInitMap
map[]
0
withInitMap
map[fuga:2 hoge:1]
1
1 true
0 false

今更ながら気づいた(正確じゃないかも。要確認)

  • 初期化子を使って初期化するときに、複数行で値を渡す場合、最後の要素の後にもカンマが必要。
    • ないと文法エラーになる。syntax error: need trailing comma before newline in composite literal
  • 複数の値を返り値とする場合、受け取り側の実装による挙動が、Rubyと少し違う?
    • 違うっぽい。
    • 返り値を返さない関数を、返り値を期待した使い方をすると関数() used as valueエラーになる。
    • 変数の数が返り値の数にあっていないと、assignment count mismatch: 2 = 1みたいなエラーがでる。
    • fmt.Printlnはうまく受け取ってくれる。
  • Mapの値に対するアクセスの戻り値は、以下の様な挙動っぽい。
    • 0個の返り値を関数の引数にする場合:1つ目の返り値が関数の引数になる。(fmt.Printlnの挙動から)
    • 1個の返り値を受け取る場合:1つ目の返り値のみ受け取る。

mapの初期化

コメントアウトを外すと、いい感じにエラーする。

試してみた2

演習のコード。

mapの演習

例えばrubyのハッシュの用に、新しいキーに対するカウントをインクリメントするときにも、zero valueで初期化されているので、キーの有無にかかわらずにインクリメントできる。

PASS
 f("I am learning Go!") = 
  map[string]int{"learning":1, "Go!":1, "I":1, "am":1}
PASS
 f("The quick brown fox jumped over the lazy dog.") = 
  map[string]int{"brown":1, "over":1, "lazy":1, "dog.":1, "the":1, "The":1, "quick":1, "fox":1, "jumped":1}
PASS
 f("I ate a donut. Then I ate another donut.") = 
  map[string]int{"I":2, "ate":2, "a":1, "donut.":2, "Then":1, "another":1}
PASS
 f("A man a plan a canal panama.") = 
  map[string]int{"panama.":1, "A":1, "man":1, "a":2, "plan":1, "canal":1}