tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【go】golangはmapは宣言だけだと `panic: assignment to entry in nil map` に...なることがあるよのメモ

はじめに

かなり初歩的ですがpanic: assignment to entry in nil map で小一時間悩んだので自分戒めメモ。
わかってるつもりが、mapの宣言と初期化を混同していましたというお恥ずかしいアレです...

panic: assignment to entry in nil map が起こった例

  • mapを宣言して
  • funcで取得した値を入れて
  • その後にdefaultでkey:valueを追加しておきたい

みたいな時にpanic: assignment to entry in nil map がでてぱっと原因がわからなくて悩みました。

あとで単純かしたpanicも載せますが、よく考えれば当たり前とはいえロジック中だと最初ほんとにわからなかった...

sample.go

package main

import "log"

func main() {
  // 宣言
  var m map[string]string
  
  // 条件に応じて取得
  // trueの時は問題無し
  // falseだと....
  if condition := false; condition {
    m = getMap()
  }

  // mapにdefaultでkey:valueを追加
  //   -> ここで `panic: assignment to entry in nil map` 
  addMapValue(&m)

  // 出力
  log.Printf("m: %+v", m)
}

// mapを取得する
func getMap() map[string]string {
  return map[string]string{"hoge": "fuga"}
}

// mapに追加する
func addMapValue(m *map[string]string) {
  // 何か処理をして

  // からの追加
  key := "piyo"
  value := "magu"
  (*m)[key] = value
}

実行結果

  • condition := true の場合
$ go run sample.go 
2017/04/11 00:38:48 m: map[hoge:fuga piyo:magu]
  • condition := false の場合
$ go run sample.go 
panic: assignment to entry in nil map

goroutine 1 [running]:
panic(0xbab40, 0x8201ce290)
  /usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
main.main()
  /Users/hoge/sample/sample.go:26 +0x162
exit status 2

原因

  • 初期化前のmapはnil
  • nilのmapに要素を割り当てられない

参考サイト Go言語:Map

要は宣言だけのmap(やsliceなどのポインタ系)はゼロ値がnilのためという事ですね。

panic: assignment to entry in nil map の単純な例

かなり単純化して書くとわかりやすいです。

func main() {
  // 宣言
  var m map[string]string

  // key:valueをsetのつもり
  // -> この時点で `panic: assignment to entry in nil map`
  m["hoge"] = "fuga"

  // 出力
  log.Printf("m: %+v", m)
}

最初から素直にこうしろって感じですね。。。

func main() {
  // 初期化
  m := map[string]string{"hoge": "fuga"}

  // 出力
  log.Printf("m: %+v", m)
}

終わり

goさわりはじめたとはいえだいぶ慣れたよな〜と思ってたころでしたが、
まだまだやん...と思いました、というメモ\(^o^)/