We can return a value from loops with break
, for example:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {result}");
}
And we can break the outer loops using labels, but is there a way to also return a value while breaking outer loops?
fn main() {
let mut count = 0;
'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up; // <-- Want to retun a value here
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
}
Loops in Rust are expressions, and while most loops evaluate to ()
, you can break
with a value, including breaking to outer labels. In the following example, this is accomplished by break 'counting_up Some(1)
and assigning the loop's value via let foo: Option<usize> = 'counting_up: loop {
Notice that the compiler will enforce that all control flow paths evaluate to the same type (that is, the type of foo
). If your loop does not produce a value in all cases, you can simply use Option
, as in the example below.
fn main() {
let mut count = 0;
// Assign the loop's value to `foo`
let foo: Option<usize> = 'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
// Value found
break 'counting_up Some(1);
}
if count == 3 {
// Break early, assign `None` to `foo`
break 'counting_up None;
}
remaining -= 1;
}
count += 1;
if count >= 42 {
// break from 'counting_loop, assign `None` to `foo`
break None;
}
};
println!("End count = {foo:?}");
}