loop_break_value
The tracking issue for this feature is: #37339
Documentation to be appended to section G of the book.
Loops as expressions
Like most things in Rust, loops are expressions, and have a value; normally () unless the loop
never exits.
A loop can instead evaluate to a useful value via break with value:
# #![allow(unused_variables)] #![feature(loop_break_value)] #fn main() { // Find the first square number over 1000: let mut n = 1; let square = loop { if n * n > 1000 { break n * n; } n += 1; }; #}
The evaluation type may be specified externally:
# #![allow(unused_variables)] #![feature(loop_break_value)] #fn main() { // Declare that value returned is unsigned 64-bit: let n: u64 = loop { break 1; }; #}
It is an error if types do not agree, either between a "break" value and an external requirement, or between multiple "break" values:
#![feature(loop_break_value)]
loop {
if true {
break 1u32;
} else {
break 0u8; // error: types do not agree
}
};
let n: i32 = loop {
break 0u32; // error: type does not agree with external requirement
};
Break: label, value
Four forms of break are available, where EXPR is some expression which evaluates to a value:
break;break 'label;break EXPR;break 'label EXPR;
When no value is given, the value () is assumed, thus break; is equivalent to break ();.
Using a label allows returning a value from an inner loop:
# #![allow(unused_variables)] #![feature(loop_break_value)] #fn main() { let result = 'outer: loop { for n in 1..10 { if n > 4 { break 'outer n; } } }; #}