2026-09-21
countdown.rs
fn countdown(mut n: u32) {
while n >= 0 {
println!("{n}");
n -= 1;
}
}
fn main() {
countdown(3);
}
countdownはnから0まで数え下ろして止めるつもりですが、正しく終了しません。何が問題で、どう直せばよいでしょうか?
Answer
nは符号なしのu32なので、負の値を取ることが型として存在しません。つまりn >= 0はnがどんな値でも常にtrueであり、この条件はループを終了させる役に立ちません(実際コンパイラも「型の範囲から見て比較が無意味」という警告を出します)。ループを実際に止めているのはnが0のときにn -= 1を実行してしまうことによる整数アンダーフローで、これはdebugビルドではパニックを起こし、releaseビルドではu32::MAXへラップアラウンドしてループが実質的に終わらなくなります。どちらにしても意図した「0まで数えて止まる」動作にはなりません。符号なし整数を負の方向へ終了条件にするのではなく、0より大きい間だけ回すようにし、最後の0はループの外で出力します:
fn countdown(mut n: u32) {
while n > 0 {
println!("{n}");
n -= 1;
}
println!("0");
}