Skip to content

Rust Loops

Rust has three ways to repeat code: loop, while, and for. This page covers loop, the simplest and most direct of the three — it repeats forever until you tell it to stop.

fn main() {
let mut count = 0;
loop {
count += 1;
println!("{count}");
if count == 3 {
break;
}
}
}

Output:

1
2
3
▶ Try it Yourself

loop on its own never stops — break is what ends it. Without that if count == 3 { break; }, this program would print forever.

Here’s something loop can do that while and for can’t: you can put a value after break, and that becomes the result of the whole loop:

fn main() {
let mut count = 0;
let result = loop {
count += 1;
if count == 10 {
break count * 2; // stop and hand back a value
}
};
println!("{result}");
}

Output:

20
▶ Try it Yourself

This is handy for things like “keep retrying until it works, then give me the result” — you’ll see this pattern in real code more than you’d expect.

Notice the semicolon after the closing } of the loop. The whole loop { ... } is the right-hand side of let result = ...;, so the let statement needs its ; at the end, just like let x = 5;.

If you come from another language, you might write an endless loop as while true { ... }. That works in Rust, but the compiler warns you:

warning: denote infinite loops with `loop { ... }`
--> src/main.rs:5:5
|
5 | while true {
| ^^^^^^^^^^ help: use `loop`

This isn’t just about style. Rust knows that the body of a loop always runs, and that the only way out is a break. It doesn’t assume that for while true, because it doesn’t look at the value of the condition. That makes a real difference when a variable gets its value inside the loop:

fn main() {
let mut n = 1;
let answer; // no value yet
loop {
if n * n > 50 {
answer = n * n; // set it right before leaving
break;
}
n += 1;
}
println!("The first square above 50 is {answer}");
}

Output:

The first square above 50 is 64
▶ Try it Yourself

With loop, Rust can see that the only way to reach println! is through that break, so answer is always set. Change loop to while true and you get error[E0381]: used binding answer is possibly-uninitialized. The compiler thinks the loop might end without running the if at all.

In practice, the cleanest version of this program uses break with a value, which you saw above: let answer = loop { ... break n * n; ... };. Either way, the lesson is the same: when you mean “forever, until I break”, write loop.

loop is the right choice when you don’t know ahead of time how many times you’ll repeat — you’re waiting for some condition to become true, rather than counting through a range or a list. For counting or iterating over a collection, while and for (covered next) usually read better.

Use loop to print a countdown from 5 to 1, then print Liftoff!. Hint: start with let mut n = 5;, and break once n reaches 0.

Show solution
fn main() {
let mut n = 5;
loop {
if n == 0 {
break;
}
println!("{n}...");
n -= 1;
}
println!("Liftoff!");
}

Output:

5...
4...
3...
2...
1...
Liftoff!
▶ Try it Yourself

The check comes first, so when n is 0 the loop stops before printing 0....

Start at 1 and keep doubling. Use break with a value to get the first number above 1000, and count how many doublings it took. Hint: keep a mut counter outside the loop, and write let power = loop { ... };.

Show solution
fn main() {
let mut value = 1;
let mut doublings = 0;
let power = loop {
value *= 2;
doublings += 1;
if value > 1000 {
break value;
}
};
println!("{power} after {doublings} doublings");
}

Output:

1024 after 10 doublings
▶ Try it Yourself

break value; ends the loop and hands value to power. The counter lives outside the loop, so it keeps its value after the loop ends.

  • loop repeats forever until a break stops it — always make sure one exists.
  • break value; stops the loop and returns value as the result of the whole loop expression.
  • Write loop, not while true: Rust knows a loop body always runs, which helps it check your variables.
  • Reach for loop when you’re repeating “until some condition happens,” not when counting a known number of times.

Quick check

1. What stops a bare loop from running forever?

2. What does writing break count * 2; inside a loop accomplish?

3. When is loop the better choice over while or for, according to this page?

4. What happens if you write while true { ... } in Rust?

Score: 0 / 4