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.
A basic loop
Section titled “A basic loop”fn main() { let mut count = 0;
loop { count += 1; println!("{count}");
if count == 3 { break; } }}Output:
123loop on its own never stops — break is what ends it. Without that if count == 3 { break; }, this program would print forever.
Returning a value from a loop
Section titled “Returning a value from a loop”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:
20This 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;.
Why loop instead of while true?
Section titled “Why loop instead of while true?”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 64With 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.
When to use loop
Section titled “When to use 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.
Practice
Section titled “Practice”1. Countdown to liftoff
Section titled “1. Countdown to liftoff”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!The check comes first, so when n is 0 the loop stops before printing 0....
2. The first power of two above 1000
Section titled “2. The first power of two above 1000”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 doublingsbreak value; ends the loop and hands value to power. The counter lives outside the loop, so it keeps its value after the loop ends.
looprepeats forever until abreakstops it — always make sure one exists.break value;stops the loop and returnsvalueas the result of the whole loop expression.- Write
loop, notwhile true: Rust knows aloopbody always runs, which helps it check your variables. - Reach for
loopwhen you’re repeating “until some condition happens,” not when counting a known number of times.
Quick check
Section titled “Quick check”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
Read more
Section titled “Read more”- Repetition with Loops — The Rust Book: the official introduction to
loop,whileandfor. - Returning Values from Loops — The Rust Book: a short section on
breakwith a value. - loop — Rust by Example: runnable examples of
loop,breakandcontinue. - Returning from loops — Rust by Example: one more small example of a loop that gives back a value.
- The
loopkeyword — standard library docs: a compact reference for howloopandbreakwork together.