Go言語

【Go Blogを読む】Go maps in action

どうも、スタディサプリ ENGLISHでTOIECに向けて英語学習のヨノです。スタディサプリ ENGLISHだけでも十分なのですが、プログラマーとしての学習もしなければということで、Go Blog を読むことにしました。

英語の長文を読みつつ、Go言語に詳しくなれるので一石二鳥!!笑

せっかく読むので要点をまとめていこうと思います。

今回は、「Go maps in action

昔の記事でGo言語の書籍にも書かれてあることなので、目新しさはありませんが...。

宣言・初期化

キーがString型、値がInt型のmapの場合、次のように宣言する。

var m map[string]int

 

ポイント

  • mapはポインタやスライスのような参照型なので、上記のmnilになる
  • nilのmapは読み込み時には空のmapのように振る舞うが、nilのmapに書き込もうとするとpanicを起こす
  • panicを起こさないためには、組み込みのmake関数を使って、mapを初期化

初期化する場合は、make 関数を使う。

m = make(map[string]int)
m = map[string]int{} // これでも同じ

 

mapのキー

mapのキーは比較可能であればどんな型でも使えます。比較可能については、 language spec で詳しく解説されている。

要は、boolean, numeric, string, pointer, channel, interface, とこれらの型のみを含むstructとarrayならキーとして使える。

 

mapと並行処理

mapを並行して使うのは安全ではありません。(Mapに同時にアクセスするのは安全ではないMaps are not safe for concurrent use

mapに対して同時に読み書きするのは安全ではない。

もし並行して実行されるゴルーチンからmapに読み書きする必要があるならばsync.RWMutexを使う。

var counter = struct{
    sync.RWMutex
    m map[string]int
}{m: make(map[string]int)}

// 読み取りロック
counter.RLock()
n := counter.m["some_key"]
counter.RUnlock()
fmt.Println("some_key:", n)

// 書き込みロック
counter.Lock()
counter.m["some_key"]++
counter.Unlock()

 

反復順序

rangeループでmapを反復するとき、反復順序は固定ではなく実行するたびに異なる。

もし安定した反復順序が必要なら、その順序を保証するデータ構造を別途用意する必要がある。

例えばキーをソートしたスライスを用意するなど。

var m map[int]string
var keys []int
for k := range m {
    keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
    fmt.Println("Key:", k, "Value:", m[k])
}

 

おすすめ図書

Tour of Goを終えた人にオススメです!!

-Go言語

© 2021 フリエン生活 Powered by AFFINGER5