index out of range パニックの原因と直し方
存在しない添字でスライスや配列にアクセスすると、コンパイルは通りますが実行時にパニックしてプログラムが異常終了します。
エラーメッセージの読み方
panic: runtime error: index out of range [5] with length 3
panic- パニック — 実行時に回復不能な状態になったことを示します。deferとrecoverで捕まえない限り、そのままプロセスが終了します
runtime error: index out of range [5] with length 3- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 package main 2 3 import "fmt" 4 5 func main() { 6 nums := []int{1, 2, 3} 7 fmt.Println(nums[5 ]) ^ 8 }
panic: runtime error: index out of range [5] with length 3length 3
numsの長さは3なので、有効な添字は0〜2です。5番目の要素は存在しません。
直し方: 5 を 1 にします。
広告
広告スロット(未設定)
パターン2
1 package main 2 3 import "fmt" 4 5 func main() { 6 nums := []int{10, 20} 7 fmt.Println(nums[4 ]) ^ 8 }
panic: runtime error: index out of range [4] with length 2length 2
要素数2のスライスに対して添字4を指定しています。有効なのは0と1だけです。
直し方: 4 を 0 にします。
パターン3
1 package main 2 3 import "fmt" 4 5 func main() { 6 nums := []int{1, 2, 3, 4, 5} 7 fmt.Println(nums[10]) ^ 8 }
panic: runtime error: index out of range [10] with length 5length 5
要素数5のスライスに10番目を指定しても存在しないため、実行時にパニックします。
直し方: 10 を 2 にします。
パターン4
1 package main 2 3 import "fmt" 4 5 func main() { 6 nums := []int{7, 8, 9} 7 fmt.Println(nums[3 ]) ^ 8 }
panic: runtime error: index out of range [3] with length 3length 3
長さ3のスライスの最後の有効な添字は2です。長さと同じ3を指定するのは範囲外です。
直し方: 3 を 0 にします。
パターン5
1 package main 2 3 import "fmt" 4 5 func main() { 6 nums := []int{100} 7 fmt.Println(nums[1 ]) ^ 8 }
panic: runtime error: index out of range [1] with length 1length 1
要素が1つしかないスライスの有効な添字は0だけです。1を指定すると範囲外になります。
直し方: 1 を 0 にします。
よくある誤解
「範囲外にアクセスしてもコンパイラが事前に止めてくれるはず」という思い込みは誤りです。添字が変数の場合、境界チェックは実行時にしか行えないため、コンパイルは通ってしまいます。
まとめ
index out of range パニックの原因と直し方は初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。