はじめに
かなり初歩的ですが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
原因
参考サイト 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^)/