Skip to content

Rust While

A while loop keeps running as long as a condition stays true. It’s the right tool when you know what you’re waiting for, even if you don’t know exactly how many times it’ll take.

fn main() {
let mut count = 1;
while count <= 5 {
println!("{count}");
count += 1;
}
}

Output:

1
2
3
4
5
▶ Try it Yourself

The condition (count <= 5) is checked before every run through the loop. As soon as it’s false, the loop ends — here, after count becomes 6.

You could write the same thing with loop and a manual if/break, but while says what you mean more directly: “keep going while this is true.” Save loop for cases where the stopping condition doesn’t fit naturally at the top of the loop.

// with while — clear and to the point
let mut n = 0;
while n < 3 {
println!("{n}");
n += 1;
}
// the same thing with loop — works, but more to read
let mut n = 0;
loop {
if n >= 3 {
break;
}
println!("{n}");
n += 1;
}

while is common for things like waiting for a value to reach a target:

fn main() {
let mut balance = 100;
while balance < 200 {
balance += 25;
println!("Balance is now {balance}");
}
println!("Reached the goal!");
}

Output:

Balance is now 125
Balance is now 150
Balance is now 175
Balance is now 200
Reached the goal!
▶ Try it Yourself

The condition can be any expression that gives a bool, so you can combine checks with && and || from the Operators page, like while balance < 200 && months < 12.

Some languages have a do { ... } while (condition) loop. It runs the body first and checks the condition afterwards, so the body always runs at least once. Rust doesn’t have it. Instead, you use loop and put the check at the end.

Here’s a case where that matters. To count the digits in a number, you can keep dividing by 10 until nothing is left. But the number 0 still has one digit, and a plain while loop never runs for it:

fn main() {
let number = 0;
// A while loop checks first, so it never runs for 0.
let mut n = number;
let mut digits = 0;
while n > 0 {
digits += 1;
n /= 10;
}
println!("while says {number} has {digits} digits");
// loop + a check at the end runs the body at least once.
let mut n = number;
let mut digits = 0;
loop {
digits += 1;
n /= 10;
if n == 0 {
break;
}
}
println!("loop says {number} has {digits} digit");
}

Output:

while says 0 has 0 digits
loop says 0 has 1 digit
▶ Try it Yourself

Change number to 4096 and both versions agree: 4 digits. The difference only shows up when the condition is false from the very start. So the rule of thumb is: if the body must run at least once, write loop with the if ... { break; } at the bottom.

There’s one more kind of while loop, while let, which keeps going as long as a value matches a pattern. It’s covered on the If Let and While Let page.

Add up 1 + 2 + 3 + … and stop as soon as the total is more than 100. Print how many numbers you added and the total. Hint: you need two mut variables, one for the next number and one for the total.

Show solution
fn main() {
let mut next = 1;
let mut total = 0;
while total <= 100 {
total += next;
next += 1;
}
println!("Added {} numbers, total is {total}", next - 1);
}

Output:

Added 14 numbers, total is 105
▶ Try it Yourself

After the last pass, next has already moved one step ahead, which is why we print next - 1. Off-by-one details like this are worth checking with a small example in your head.

Start with 1000. While the number is greater than 1, divide it by 2 (integer division) and print it. At the end, print how many halvings it took. Hint: n /= 2 divides n by 2 and drops the remainder.

Show solution
fn main() {
let mut n = 1000;
let mut steps = 0;
while n > 1 {
n /= 2;
steps += 1;
println!("{n}");
}
println!("It took {steps} halvings to reach 1");
}

Output:

500
250
125
62
31
15
7
3
1
It took 9 halvings to reach 1
▶ Try it Yourself

125 / 2 is 62, not 62.5, because both numbers are integers. That’s what makes the loop finish exactly at 1.

  • while condition { ... } repeats as long as the condition is true, checked before each run.
  • Make sure something inside the loop eventually makes the condition false, or it’ll run forever.
  • Prefer while over loop whenever the stopping condition fits naturally as “while X holds.”
  • Rust has no do-while. When the body must run at least once, use loop with the break check at the end.

Quick check

1. What's the classic mistake that causes an infinite while loop?

2. When should you prefer while over loop, per this page?

3. How do you write a loop whose body always runs at least once?

Score: 0 / 3