TL;DR loop
is an expression; while true
is a statement, they have different use cases and offer flexibility and expressiveness.
The main reason is that loop
blocks are expressions, whereas while
blocks are statements. Differentiating the both and setting distinct rules for each case allows the compiler to make optimizations without sacrificing safety.
While loop
and while true
loops have the same behavior (and probably similar optimizations—the condition checking at the beginning of each while true
loop iteration is dropped for performance), they are still bound to their Rust implementations, and cannot be used interchangeably.
For instance, we can use loop
loops like this:
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // Return a value from the loop
}
};
println!("The result is {}", result); // The result is 20
We can see that we assign the evaluation of the loop
expression to result with no problems.
On the other hand, while
loops are statements, and so we cannot assign them to variables, etc.
Doing the same with a while true
loop would look like this:
let mut counter = 0;
let mut result = 0;
while counter < 10 {
counter += 1;
if counter == 10 {
result = counter * 2; // Assign a value inside the loop
break;
}
};
println!("The result is {}", result); // The result is 20
If we tried to implement this simple algorithm using while true
in the same way as loop
would yield the following compiler error:
let mut counter = 0;
let mut result = while counter < 10 {
counter += 1;
if counter == 10 {
counter * 2; // Statement, hence () is returned
break
}
};
println!("The result is {}", result); // `()` cannot be formatted with the default formatter
error[E0277]: `()` doesn't implement `std::fmt::Display`
--> src/main.rs:10:34
|
10 | println!("The result is {}", result); // The result is 20
| ^^^^^^ `()` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)