Namaran

Code daily. Without assist.

2026-09-21

countdown.rs

fn countdown(mut n: u32) {
    while n >= 0 {
        println!("{n}");
        n -= 1;
    }
}

fn main() {
    countdown(3);
}

countdownnから0まで数え下ろして止めるつもりですが、正しく終了しません。何が問題で、どう直せばよいでしょうか?

Answer

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

fn countdown(mut n: u32) {
    while n > 0 {
        println!("{n}");
        n -= 1;
    }
    println!("0");
}