map生成方法と操作について理解しよう!Go言語の辞書型です

Go言語
この記事は約12分で読めます。
Go初学者
Go初学者

他のプログラミング言語で、キーと値をセットにしてデータを扱う方法がGo言語のはないの?

この記事ではGo言語のmapについて理解できます!
  • mapの生成する方法を3種類について
  • mapの操作方法について
    1. 値の取り出し
    2. rangeを使用した値の取り出し
    3. 値の更新
    4. 値の追加
    5. 要素の削除
  • mapの要素の存在チェック

Pythonの辞書型やRubyのハッシュのように、キーと値をセットにしてデータを扱う方法がGo言語にも用意されています。

Go言語では map と呼ばれていて、キーに固有名詞などわかりやすいものを指定しておくとデータの取り出しがとても柔軟に行うことができます。

今回は、Go言語のmapについてお伝えしていきます。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

【Go言語・map】生成方法3種類

Go言語ではmapの生成方法が3種類用意されています。

それぞれの生成方法についてお伝えしていきましょう。

【生成方法1】mapの基本的な生成方法(varを使用する)

mapの生成方法の最初にお伝えするのが、変数宣言などでも使用した var を使ったmap生成方法です。

var map名 = map[キーの型]値の型{キー1: 値1, キー2: 値2, …}

では、実際にプログラムで確認していきましょう。

// 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を生成してみましょう。

map名 := map[キーの型]値の型{キー1:値1, キー2:値2, …}

では、プログラムで確認してみます。

// 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()関数は使用できます。

map名 := make(map[キーの型]値の型)

では、プログラムで確認しましょう。

// 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名[キー] = 値

// 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名[新たなキー] = 値

で追加できます。

もちろん型は合わせるようにしてください。

// 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() 関数で要素を削除できます。

delete(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)

    // 値の削除
    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についてお伝えしてきました。

それでは、まとめに入りましょう。

Go言語のmapで押さえておくこと!
  • mapの基本的な生成方法(varを使用する)
    var map名 = map[キーの型]値の型{キー1: 値1, キー2: 値2, …}
  • varを省略した形でmapを生成
    map名 := map[キーの型]値の型{キー1:値1, キー2:値2, …}
  • make()関数を使用したmapの生成
    map名 := make(map[キーの型]値の型)
  • mapはデータの順番を保証しない
  • mapの値の取り出しはキーを指定してする
  • rangeを使用してmapの値を取り出すことができる
  • mapの値の更新 map名[キー] = 値
  • mapの値の追加 map名[新たなキー] = 値
  • mapの要素の削除 delete(map名, 削除したいキー)
  • mapの要素はエラーハンドリングで存在チェックできる

以上です。

覚えることが多いですが、mapは使用する頻度も高いので実際にコードを書きながら習得していきましょう!

comment

タイトルとURLをコピーしました