Sometimes you have a loop that where the exit condition of the loop is complex, or for other reason you don't want to put it in the while condition.
In some languages there is a do while
loop that executes the first iteration and only after that checks the condition for the first time.
In Rust you could write something like:
while true {
...
if end-condition {
break;
}
}
but it is better written with the loop keyword.
loop {
...
if end-condition {
break;
}
}
The loop
loop is different from the while loop or from the for loop in that it can also return a value.
So we can write:
let result = loop {
...
if end-condition {
break 42;
}
}
Let's see a full example. This is quite similar to what we had showing the while loop, but this time the break
returns
the last number.
The dependency
In this example we use the rand crate.
[package]
name = "loop-loop"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
The code
examples/loop-loop/src/main.rs
use rand::Rng;
fn main() {
let mut total = 0;
let result = loop {
let number = rand::thread_rng().gen_range(1..=10);
total += number;
println!("{total}");
if total > 50 {
break total;
}
};
println!("The result is {result}");
}
Output
On every run we'll get a different series of numbers:
$ cargo run -q
7
16
24
27
37
46
48
58
The result is 58
Infinite loop
I used to call such loops "infinite loops" and the rust documentation of loop uses the expression Loop indefinitely,
but recently I started to feel that it isn't the right description. Of course there might be cases when you would like to loop indefinitely,
I just have never encountered one. Every time I used this construct I had some kind of exit-condition so I used break
at least once.
That's why these days I use the term "loops where the condition is checked in the body of the loop". It is longer than "infinite loops", but I feel it describes the real-world use-cases better.