Code Fix

初級

assignment to entry in nil map の原因と直し方

makeで初期化していないnilのマップに要素を書き込もうとすると、実行時にパニックが発生します。マップのゼロ値はnilで、読み取りはできても書き込みはできません。

エラーメッセージの読み方

panic: assignment to entry in nil map
panic
パニック — 実行時に回復不能な状態になったことを示します。deferとrecoverで捕まえない限り、そのままプロセスが終了します
assignment to entry in nil map
詳細メッセージ — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  package main
 2  
 3  func main() {
 4  	var m map[string]int     
                 ^
 5  	m["a"] = 1
 6  }
panic: assignment to entry in nil map

var mで宣言しただけのマップはnilで、要素の読み取りはできても書き込みはできません。makeで初期化する必要があります。

直し方: var m map[string]int を m := make(map[string]int) にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  package main
 2  
 3  func main() {
 4  	var m map[string]int     
                 ^
 5  	m["total"] = 100
 6  }
panic: assignment to entry in nil map

マップのゼロ値はnilです。書き込みを行う前に必ずmakeで実体を作る必要があります。

直し方: var m map[string]int を m := make(map[string]int) にします。

この問題を解いてみる →

パターン3

 1  package main
 2  
 3  func main() {
 4  	var m map[string]string     
                   ^
 5  	m["name"] = "go"
 6  }
panic: assignment to entry in nil map

値の型がstringでも同じで、nilマップへの書き込みは型によらずパニックします。

直し方: var m map[string]string を m := make(map[string]string) にします。

この問題を解いてみる →

パターン4

 1  package main
 2  
 3  func main() {
 4  	var m map[int]string     
                 ^
 5  	m[1] = "one"
 6  }
panic: assignment to entry in nil map

キーの型がintでも同様に、初期化前のnilマップへの書き込みはパニックの原因になります。

直し方: var m map[int]string を m := make(map[int]string) にします。

この問題を解いてみる →

パターン5

 1  package main
 2  
 3  func main() {
 4  	var m map[string]bool     
                  ^
 5  	m["ok"] = true
 6  }
panic: assignment to entry in nil map

読み取り専用の用途ならnilマップでも動きますが、書き込みが必要な時点でmakeによる初期化が必須です。

直し方: var m map[string]bool を m := make(map[string]bool) にします。

この問題を解いてみる →

よくある誤解

「var で宣言した時点で、マップは空の状態で書き込み可能になっているはず」という思い込みは誤りです。マップのゼロ値はnilであり、make(map[K]V)で明示的に初期化しない限り要素を追加できません。

実務での勘所

nilマップは書き込みだけがパニックし、読み取りは安全です。nilのmap[string]intに対してm["key"]と読み取ると、パニックせずにその値の型のゼロ値(この場合は0)が返ってきます。書き込み(m["key"] = 1)だけがパニックの対象です。この非対称性のせいで、読み取りだけのテストでは「動いているように見える」状態のまま、実際に値を追加しようとした瞬間に初めてパニックが発覚することがあります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)