I am very new to Rust and to low-level languages in general. I noticed that in the code below, if I replace loop
with while true
the code doesn't compile anymore. I would actually expect the version with loop
not to compile as well, because the return statement is inside an if statement, so not all code paths would return a value.
pub fn two_sum(numbers: Vec<i32>, target: i32) -> Vec<i32> {
let mut left = 0;
let mut right = numbers.len() - 1;
loop {
while numbers[left] numbers[right] > target {
right -= 1;
}
if numbers[left] numbers[right] == target {
break vec![left as i32 1, right as i32 1];
} else {
left = 1;
}
}
}
I am also open to suggestions on how to make the code above more Rust idiomatic!
CodePudding user response:
That is because loop
's control flow is much better understood by the compiler:
- the compiler understands that a
loop
is executed at least once - a
loop
without abreak
has type!
(never), which unifies with all types (in type-system lingo it's a "bottom" type), a loop with abreak
has type()
, a loop with a valuedbreak
has whatever typebreak
's value has - this means the compiler can reason about loop termination (or the lack thereof), if the loop does not contain a
break
statement it knows that the code following the loop is dead, it can never execute
None of that is the case of a while
loop, there is no special-case for while true
, or while false
, they're not treated any differently than any other while
loop: as far as the compiler is concerned they can all run for 0 iterations
Hence:
let mut a;
loop {
a = 1;
break;
}
a
compiles but
let mut a;
while true {
a = 1;
break;
}
a
does not compile. That is also why loop
can have a result value but while
can not.