attempt to divide by zero パニックの原因と直し方
整数を0で割ると、実行時にパニックが発生しプログラムが異常終了します。0になりうる値は、割り算の前に事前チェックが必要です。
エラーメッセージの読み方
thread 'main' panicked at main.rs:4:20:
main.rs- ファイル名
4- 行番号 — 実際にクラッシュした行
20- 列番号
panicked- パニック — 実行時に回復不能な状態になったことを示します。tryやResultで捕まえない限り、そのままプロセスが終了します
attempt to divide by zero- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 fn main() { 2 let checked_in: Vec<i32> = vec![ ]; ^ 3 let total_score = 450; 4 println!("{}", total_score / checked_in.len() as i32); 5 }
thread 'main' panicked at main.rs:4:20:
attempt to divide by zero
checked_inの要素数(len)が0だと、それで割る計算はゼロ除算になりパニックします。
直し方: (空) を 1 にします。
広告
広告スロット(未設定)
パターン2
1 fn main() { 2 let full_boxes: Vec<i32> = vec![ ]; ^ 3 let budget = 1000; 4 println!("{}", budget / full_boxes.len() as i32); 5 }
thread 'main' panicked at main.rs:4:20:
attempt to divide by zero
整数を0で割ると、Rustは実行時にパニックしてプログラムを止めます。
直し方: (空) を 1 にします。
パターン3
1 fn main() { 2 let successful_attempts: Vec<i32> = vec![ ]; ^ 3 let hits = 96; 4 println!("{}", hits / successful_attempts.len() as i32); 5 }
thread 'main' panicked at main.rs:4:20:
attempt to divide by zero
0になりうる値を分母に使う前には、事前にチェックする必要があります。
直し方: (空) を 1 にします。
パターン4
1 fn main() { 2 let travel_days: Vec<i32> = vec![ ]; ^ 3 let distance = 300; 4 println!("{}", distance / travel_days.len() as i32); 5 }
thread 'main' panicked at main.rs:4:20:
attempt to divide by zero
浮動小数点数同士の0除算はinfになりますが、整数同士では必ずパニックする点に注意してください。
直し方: (空) を 1 にします。
パターン5
1 fn main() { 2 let full_groups: Vec<i32> = vec![ ]; ^ 3 let people = 40; 4 println!("{}", people / full_groups.len() as i32); 5 }
thread 'main' panicked at main.rs:4:20:
attempt to divide by zero
分母になりうる値が空である可能性を考慮しないと、実行時にパニックする危険があります。
直し方: (空) を 1 にします。
よくある誤解
「0で割っても何かの特別な値が返ってくるはず」という思い込みは整数の割り算には当てはまりません。浮動小数点数(f64)同士の割り算ならinfになりますが、整数同士では必ずパニックします。
まとめ
attempt to divide by zero パニックの原因と直し方は初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。