Skip to content

Instantly share code, notes, and snippets.

@tokubass
Created June 8, 2016 09:58
Show Gist options
  • Save tokubass/7edd96ade864f718100eeccfac186754 to your computer and use it in GitHub Desktop.
Save tokubass/7edd96ade864f718100eeccfac186754 to your computer and use it in GitHub Desktop.
The Go Programming Language - ch4 map

4.3 Maps

宣言

map [K] V //Kがkeyのtype、Vがvalueのtype

比較

  • Keyは==で比較する。
  • floating-pointで==比較はしてはいけない。chapter3参照。
  • 特にNaNとはダメ

make

  • makeはsliceとmapを作れる
  • 初期値を伴う宣言の場合はmakeはいらない。
// pattern 1
ages := make(map[string]int)

// pattern 2
ages := map[string]int{ // makeなし
   "alice": 31,
   "charlie": 34,
}

// pattern 3
ages := make(map[string]int)
ages["alice"] = 31
ages["charlie"] = 34

// empty map
ages := map[string]int{}


delete(ages, "alice")

存在しないkeyのvalue値

  • zero valueになる
  • 本当に存在しなかったかどうかはフラグをチェック
val, ok := ages["hoge"]
if !ok {}

演算

ages["hoge"] = ages["hoge"] + 1
ages["hoge"] += 1
ages["hoge"]++

mapのアドレス

  • map elementのアドレスは得られない
    • rehashでアドレスが変化するから
  • &ages["alice"]はコンパイルエラー

mapは順序不定

  • range-based for loopででkey,valueがとれる。
  • しかし順番はランダム(rangeを実行する度に順番かわる)
for name,age := range ages {

}

mapとnil

  • delete,len,range はnilなmapで安全.空のmapと同じように振る舞う
  • しかし、makeでallocateする前に代入しようとするとpanicになる

比較

  • mapどうしの比較はできない
  • 唯一 == nilだけ可能

mapを利用してset型作成

  • Goはset型を提供していない
    • 重複する要素をもたない、順序づけられていない要素の集まり
  • mapはkeyの重複がないことを利用して作成
  • それを説明するためにdedupというプログラムを紹介
    • 各行をreadしてprint、ただし重複した行コンテンツはprintしない。
    • https://github.com/adonovan/gopl.io/blob/master/ch4/dedup/main.go
    • (if err := input.Err(); err != nil っていつ発生するんだろ)
    • ただしいつもmap[string]boolがシンプルなset型にはならないことに注意
      • セット型がリストだから?単純にkeyをとりだしただけだと、falseのkeyも取得できてしまう

mapのkeyとslice

  • mapのkeyにsliceは使えるか?

    • 使えない
    • mapのkeyは比較可能でなければならない
    • sliceは比較には使えない
  • sliceの内容を一つの文字列にして、mapのkeyとする

    • slice以外でも応用できる
	ages := map[string]int{
		"alice":   31,
		"charlie": 34,
	}
	ages2 := map[string]int{
		"alice":   31,
		"charlie": 34,
	}

	str := fmt.Sprintf("%q", ages)
	str2 := fmt.Sprintf("%q", ages2)
	fmt.Printf("%v", str == str2) // true

mapを使ったサンプルコード

  • inputのUnicode code pointをカウントする
  • r, n, err := in.ReadRune() // returns rune, nbytes, error
  • 読み込み失敗すると、変わりの文字(ReplacementChar=U+FFFD)がrに入る if r == unicode.ReplacementChar && n == 1 {

mapの中にmapを入れるサンプルコード

https://github.com/adonovan/gopl.io/blob/master/ch4/graph/main.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment