range end index out of range for slice パニックの原因と直し方
配列やVecをスライスする際、範囲の終端が要素数を超えているとパニックします。スライス構文v[a..b]は、bが要素数以下であることが前提です。
エラーメッセージの読み方
thread 'main' panicked at main.rs:3:15:
main.rs- ファイル名
3- 行番号 — 実際にクラッシュした行
15- 列番号
panicked- パニック — 実行時に回復不能な状態になったことを示します。tryやResultで捕まえない限り、そのままプロセスが終了します
range end index 5 out of range for slice of length 3- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 fn main() { 2 let v = vec![1, 2, 3]; 3 let s = &v[1..5]; ^ 4 println!("{:?}", s); 5 }
thread 'main' panicked at main.rs:3:15:
range end index 5 out of range for slice of length 3
vの要素数は3なので、範囲の終端に指定できる最大値は3です。5を指定すると範囲外でパニックします。
直し方: 5 を 3 にします。
広告
広告スロット(未設定)
パターン2
1 fn main() { 2 let letters = vec!['a', 'b', 'c', 'd']; 3 let s = &letters[0..10]; ^ 4 println!("{:?}", s); 5 }
thread 'main' panicked at main.rs:3:21:
range end index 10 out of range for slice of length 4
スライスの範囲は要素数を超えることができません。超えるとその場でパニックします。
直し方: 10 を 4 にします。
パターン3
1 fn main() { 2 let nums = vec![10, 20, 30, 40, 50]; 3 let s = &nums[2..9]; ^ 4 println!("{:?}", s); 5 }
thread 'main' panicked at main.rs:3:18:
range end index 9 out of range for slice of length 5
配列やVecの範囲外アクセスと同様、スライスの範囲チェックも実行時に行われます。
直し方: 9 を 5 にします。
パターン4
1 fn main() { 2 let names = vec!["a", "b", "c"]; 3 let s = &names[1..7]; ^ 4 println!("{:?}", s); 5 }
thread 'main' panicked at main.rs:3:19:
range end index 7 out of range for slice of length 3
存在する分だけ切り取ってくれるような寛容な動作はせず、範囲が不正なら即座にパニックします。
直し方: 7 を 3 にします。
パターン5
1 fn main() { 2 let data = vec![1.1, 2.2, 3.3]; 3 let s = &data[0..6]; ^ 4 println!("{:?}", s); 5 }
thread 'main' panicked at main.rs:3:18:
range end index 6 out of range for slice of length 3
要素数を勘違いしてスライスの終端を大きく指定すると、range end index out of rangeでパニックします。
直し方: 6 を 3 にします。
よくある誤解
「範囲外を指定しても、存在する分だけ切り取ってくれるはず」という思い込みは誤りです。Rustのスライスは指定した範囲が完全に有効でないとパニックし、存在する分だけ返すような寛容な動作はしません。
まとめ
range end index out of range for slice パニックの原因と直し方は中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。