Goコレクション   マップ

ホーム   Goチュートリアル
目次


マップとは

  1. マップは、インデックス番号の代わりに、キーによって要素を管理するコレクションです。

  2. キーには整数、浮動小数点数なども使えますが、文字列を使うのが一般的です。

  3. マップは、他の言語では、辞書、ハッシュ、連想配列などと呼ばれています。

  4. マップは、インデックス番号で管理されていないので、要素の順序という概念はありません。

  5. マップは、もとのマップに要素の追加と削除ができます。

  6. マップは、参照型のコレクションです。マップ名はポインターとして使えます。

map1.go


package main

import "fmt"

func main() {
	
	m := make(map [string] int)
	var m_ map[string] int
	
	println(m )
	println(m_)
	fmt.Println(m )
	fmt.Println(m_)
	
	m["math"] = 100
	//m_["math"] = 100	panic: assignment to entry in nil map というエラーになります
	
	println(m )
	fmt.Println(m )
}
	

実行結果


0xc00007e000
0x0
map[]
map[]
0xc00007e000
map[math:100]
	

コード説明


	m := make(map[string] int)
	

要素のない空のマップの定義は、make 関数と map キーワードを使った簡略定義になります。map キーワードに続く [ と ] の間に、キーの型を指定し、続いて値の型を指定します。このコードでは、string 型のキーと、int 型の値という要素を格納できる、空のマップ(要素のないマップ)が定義されています。


	var m_ map[string] int
	

var を使っても、空のマップを定義できるように見えますが、この定義方法で作ったマップは実際には使用できません。


	m["math"] = 100
	

マップに要素を追加するには、キーを指定し、値を代入するだけです。もしマップに同じキーの要素がある場合は、その要素の値が書き換わりますので注意してください。


	//m_["math"] = 100	panic: assignment to entry in nil map というエラーになります
	

var で定義した、マップ m_ に要素を追加しようとしても、エラーになります。


	println(m )
	

要素を追加する前のマップ m と、要素を追加した後のマップ m は、同じアドレスになります。マップはスライスと違い、もとのマップに要素を追加します。

var で定義したマップ m_ に要素を追加できなかったのは、実態のない(アドレスのない)マップに要素を追加することはできないからです。
var で定義したスライスに append で要素を追加できたのは、append は、実体のある(アドレスのある)新しいスライスを作るからです。


	fmt.Println(m )
	

要素のないマップの値は、map[ ] と表示されます。math 要素を追加したマップは、map[math:100]と表示されます。キーと値は : で区切られます。

要素の初期化と削除

map2.go


package main

import "fmt"

func main() {
	
	score := map [string] int {"math":100, "science":80, "english":60}
	
	fmt.Println(score)
	println(score)
	println(len(score))
	
	delete(score, "math")
	delete(score, "music")
	
	fmt.Println(score)
	println(score)
	println(len(score))
	
	v1 , exist := score["science"]
	println(v1, exist)
	v2 , exist := score["english"]
	println(v2 , exist)
	v_, exist := score["art"]
	fmt.Printf("%2d %t\n", v_, exist)
}
	

実行結果


map[english:60 math:100 science:80]
0xc000082000
3
map[english:60 science:80]
0xc000082000
2
80 true
60 true
 0 false
	

コード説明


	score := map [string] int {"math":100, "science":80, "english":60}
	

マップの定義と初期化を同時にする場合には、make 関数は使いません。初期値は、キー : 値という形で要素を記述し、各要素は , (コンマ)で区切り、全体を { と }(波括弧)で囲みます。


	println(len(score))
	

マップでも len 関数は使えます。しかし、cap 関数は使えません。マップには容量という概念はないみたいです。


	delete(score, "math")
	delete(score, "music")
	

マップの要素の削除は delete 関数で行います。第 1 引数にマップを、第 2 引数に、削除する要素のキーを指定します。該当する要素が存在していた場合は、その要素を削除し、該当する要素が存在しない場合は、何もしません。


	println(score)
	

println 関数の引数にコレクションを渡した場合は、そのコレクションのアドレスが表示されます。コレクションが参照型の場合は、その変数名をそのまま記述すれば OK ですが、コレクションが値型の場合は、&変数名と変数名の前に &(アンパサンド)を付けなければエラーになります。マップの場合は、変数名をそのまま渡せるので、参照型であることが分かります。

マップのアドレスは、要素を削除する前も後も同じアドレスになります。同じマップであることが分かります。


	v1 , exist := score["science"]
	

上記のように記述すると、マップに、キーの要素が存在するかどうかが分かります。v1 と exist は、任意の変数名です。v1 に要素の値が、exist に要素が存在するかどうかの bool 値が代入されます。


	v2 , exist := score["english"]
	

このコードの場合、値を受ける変数は、なぜか使い回しができません。bool 値を受ける変数は使い回しができます。


	fmt.Printf("%2d %t\n", v_, exist)
	

fmt.Printf 関数のフォーマット文で、bool値の書式指定は、%t です。このような書式指定 %t のことを書式指定子と言います。

マップの繰り返し処理

map3.go


package main

import "fmt"

func main() {
	
	score := map [string] int {"math":100, "science":80, "english":60}
	
	for k, v := range score {
		fmt.Printf("%10s: %3d\n", k, v)
	}
}
	

実行結果


      math: 100
   science:  80
   english:  60
	

コレクションまとめ

第 2 部コレクションでは、配列、スライス、マップを紹介しました。

マップは、同じアドレスに要素の追加と削除ができる参照型です。一番使いやすいように感じます。

スライスは、同じ変数にアドレスに要素の追加はできませんが、参照型です。要素を順序で管理したい場合に便利です。


83 visits
Posted: Jul. 02, 2019
Update: Jul. 02, 2019

ホーム   Goチュートリアル   目次