
他のプログラミング言語で、キーと値をセットにしてデータを扱う方法がGo言語のはないの?
Pythonの辞書型やRubyのハッシュのように、キーと値をセットにしてデータを扱う方法がGo言語にも用意されています。
Go言語では map
と呼ばれていて、キーに固有名詞などわかりやすいものを指定しておくとデータの取り出しがとても柔軟に行うことができます。
今回は、Go言語のmapについてお伝えしていきます。
【Go言語・map】生成方法3種類
Go言語ではmapの生成方法が3種類用意されています。
それぞれの生成方法についてお伝えしていきましょう。
【生成方法1】mapの基本的な生成方法(varを使用する)
mapの生成方法の最初にお伝えするのが、変数宣言などでも使用した var
を使ったmap生成方法です。
では、実際にプログラムで確認していきましょう。
// mapの基本的な生成方法(varを使用する)
package main
import "fmt"
func main() {
// 記述方法 map[キーの型]値の型{キー1:値1, キー2:値2, ...}
var map1 = map[string]int{"Apple": 180, "Banana": 200, "Orange": 300}
fmt.Println(map1)
}
// 出力結果
$ go run main.go
map[Apple:180 Banana:200 Orange:300]
map
としてキーと値がセットで配列としてデータが格納されています。
【生成方法2】varを省略した形でmapを生成
それでは、var
を省略した形でmapを生成してみましょう。
では、プログラムで確認してみます。
// varを省略した形でmapを生成
package main
import "fmt"
func main() {
map2 := map[string]int{"Orange": 200, "Pain": 300, "Apple": 150}
fmt.Println(map2)
}
// 出力結果
$ go run main.go
map[Apple:150 Orange:200 Pain:300] // ここに注目!
ここで注目してほしいのは、mapはデータの順番を保証しません。
もし、自分でコードを書いて出力結果が順番通りでなくても正常ですので注意しましょう。
キーと値を改行付きで書く
初期化の段階でデータが少ないと1行で書いても問題ありませんが、多くなってくると見にくいプログラムになります。
それを防ぐために、Go言語では改行してキーと値を記述することができます。
// キーと値を改行付きで書く
package main
import "fmt"
func main() {
map3 := map[int]string{
1: "morip", //行末に「,」を忘れずにつける
2: "Golang",
3: "PHP",
4: "HTML",
5: "Ruby",
}
fmt.Println(map3)
}
// 出力結果
$ go run main.go
map[1:morip 2:Golang 3:PHP 4:HTML 5:Ruby]

プログラムも見やすくなりますね!
注意点としては、キーと値の行末には , を忘れずにつけましょう。
【生成方法3】make()関数を使用したmapの生成
make()関数は、スライスの生成の時にも学習した関数です。
mapの生成でも、make()関数は使用できます。
では、プログラムで確認しましょう。
// make()関数を使用したmapの生成
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
}
// 出力結果
$ go run main.go
map[]
空のmapが生成されています。
make()関数でmapを生成すると、メモリ上に map
の領域が確保されています。
【Go言語・map】値の取り出し・更新・追加・削除
生成したmapから値の取り出し・更新・追加・削除についてプログラムを見ながら確認していきましょう。
mapの値の取り出し
生成したmapから値を取り出します。
取り出す方法としては、キーを指定して取り出します。
// mapの値の取り出し
package main
import "fmt"
func main() {
var map1 = map[string]int{"Apple": 180, "Banana": 200, "Orange": 300}
fmt.Println(map1)
// キーを指定して値を取り出す
fmt.Println(map1["Apple"])
}
// 出力結果
$ go run main.go
180
キーが "Apple"
の値 180
が出力されています。
rangeを使用した値の取り出し
mapでもスライスと同様に range
を使用して値を取り出すことができます。
// rangeを使ってmapの値を取り出す
package main
import "fmt"
func main() {
m1 := map[string]int{
"Apple": 180,
"Banana": 230,
"Orange": 210,
}
// キーと値の両方を取り出す時
for k, v := range m1 {
fmt.Println(k, v)
}
// 値だけ取り出す場合
for _, v := range m1 {
fmt.Println(v)
}
// キーだけ取り出す場合
for k := range m1 {
fmt.Println(k)
}
}
// 出力結果
$ go run main.go
Apple 180 // キーと値の両方を取り出した結果
Banana 230
Orange 210
180 // 値だけ取り出した結果
230
210
Apple // キーだけ取り出した結果
Banana
Orange
注意点としては、値だけ取り出す時にキーの変数を _ に変更することです。
mapの値の更新
mapの値の更新を確認していきましょう。
mapのキーを指定してして、更新したい値を記述します。
// mapの値の変更
package main
import "fmt"
func main() {
map3 := map[int]string{
1: "morip",
2: "Golang",
3: "PHP",
4: "HTML",
5: "Ruby",
}
fmt.Println(map3)
// 値の更新
map3[1] = "C言語"
fmt.Println(map3)
}
// 出力結果
$ go run main.go
map[1:morip 2:Golang 3:PHP 4:HTML 5:Ruby]
map[1:C言語 2:Golang 3:PHP 4:HTML 5:Ruby]
キー 1
の値が morip
から C言語
に更新されているが確認できます。
mapの値の追加
mapではスライスで使用できたappend()関数が使用できません。
で追加できます。
もちろん型は合わせるようにしてください。
// mapの値の追加
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
// 値を追加する
map4["Hokkaido"] = "Sapporo"
map4["Aomori"] = "Aomori"
map4["Iwate"] = "Morioka"
fmt.Println(map4)
}
// 出力結果
$ go run main.go
map[]
map[Aomori:Aomori Hokkaido:Sapporo Iwate:Morioka]
値が追加されているのが確認できます。
mapの要素の削除
map関数では delete() 関数で要素を削除できます。
// mapの要素の削除
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
// 値を追加する
map4["Hokkaido"] = "Sapporo"
map4["Aomori"] = "Aomori"
map4["Iwate"] = "Morioka"
fmt.Println(map4)
// 値の削除
delete(map4, "Iwate")
fmt.Println(map4)
}
// 出力結果
$ go run main.go
map[]
map[Aomori:Aomori Hokkaido:Sapporo]
キーが Iwate
値が Morioka
が削除されているのが確認できます。
mapの要素の存在チェック
mapでは値を取り出す際に、mapに存在しないキーを指定してもエラーにならずに型の初期値が出力されてしまいます。
// mapの要素の削除
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
map4["Hokkaido"] = "Sapporo"
map4["Aomori"] = "Aomori"
map4["Iwate"] = "Morioka"
fmt.Println(map4)
// 登録されていない値を取得すると…
// 指定した型の初期値が帰ってくる
fmt.Println(map4["Okinawa"])
}
// 出力結果
$ go run main.go
今回のmapでは値の型が string
なので空文字が出力されます。
値が無いのにプログラムがエラーを起こさずに実行すると、バグに繋がりかねません。
そこで、Go言語ではmapの値の取り出しに、値のアリナシを判定も戻り値として返ってきます。

mapの値の取り出しは2つの戻り値が返ってきます。
それでは、mapの要素の存在チェックするプログラムを確認しましょう。
// mapの要素の削除
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
map4["Hokkaido"] = "Sapporo"
map4["Aomori"] = "Aomori"
map4["Iwate"] = "Morioka"
fmt.Println(map4)
// mapのエラーハンドリング
// 戻り値が2つあるのを利用する
str, ok := map4["Okinawa"]
if !ok {
fmt.Println("値がありません。")
}
fmt.Println(str, ok)
}
// 出力結果
$ go run main.go
値がありません。
false
if文でエラーハンドリングして、okでなかったら(!ok) if文の処理が実行されます。
今回はmapに Okinawa が無かったので、if文が実行され 値がありません。 と出力されました。
fmt.Println(str, ok)
は、値と値のアリナシの判定を出力していて、値が無いので strは空文字 で okは false が出力されています。

ちなみに ok
は変数名なので abc
でも、なんでも大丈夫です!
ちなみに、mapに値が存在する場合は…
// mapの要素の削除
package main
import "fmt"
func main() {
map4 := make(map[string]string)
fmt.Println(map4)
map4["Hokkaido"] = "Sapporo"
map4["Aomori"] = "Aomori"
map4["Iwate"] = "Morioka"
fmt.Println(map4)
str, ok := map4["Aomori"]
if !ok {
fmt.Println("値がありません。")
}
fmt.Println(str, ok)
}
// 出力結果
$ go run main.go
Aomori true
if文のエラーハンドリングは無視され、値 Aomori と 値の判定 true と出力されています。
【まとめ】Go言語でのmap生成方法と操作
今回はGo言語のmapについてお伝えしてきました。
それでは、まとめに入りましょう。
以上です。
覚えることが多いですが、mapは使用する頻度も高いので実際にコードを書きながら習得していきましょう!
comment