Loops
Syntax
LoopExpression :
LoopLabel? (
InfiniteLoopExpression
| PredicateLoopExpression
| PredicatePatternLoopExpression
| IteratorLoopExpression
)
Rust supports four loop expressions:
- A
loopexpression denotes an infinite loop. - A
whileexpression loops until a predicate is false. - A
while letexpression tests a refutable pattern. - A
forexpression extracts values from an iterator, looping until the iterator is empty.
All four types of loop support break expressions,
continue expressions, and labels.
Only loop supports evaluation to non-trivial values.
Infinite loops
Syntax
InfiniteLoopExpression :
loopBlockExpression
A loop expression repeats execution of its body continuously:
loop { println!("I live."); }.
A loop expression without an associated break expression is diverging and
has type !. A loop expression containing
associated break expression(s) may terminate, and must
have type compatible with the value of the break expression(s).
Predicate loops
Syntax
PredicateLoopExpression :
whileExpressionexcept struct expression BlockExpression
A while loop begins by evaluating the boolean loop conditional expression. If
the loop conditional expression evaluates to true, the loop body block
executes, then control returns to the loop conditional expression. If the loop
conditional expression evaluates to false, the while expression completes.
An example:
# #![allow(unused_variables)] #fn main() { let mut i = 0; while i < 10 { println!("hello"); i = i + 1; } #}
Predicate pattern loops
Syntax
PredicatePatternLoopExpression :
whileletPattern=Expressionexcept struct expression BlockExpression
A while let loop is semantically similar to a while loop but in place of a
condition expression it expects the keyword let followed by a refutable
pattern, an =, an expression and a block expression. If the value of the expression on
the right hand side of the = matches the pattern, the loop body block executes then
control returns to the pattern matching statement. Otherwise, the while
expression completes.
# #![allow(unused_variables)] #fn main() { let mut x = vec![1, 2, 3]; while let Some(y) = x.pop() { println!("y = {}", y); } #}
Iterator loops
Syntax
IteratorLoopExpression :
forPatterninExpressionexcept struct expression BlockExpression
A for expression is a syntactic construct for looping over elements provided
by an implementation of std::iter::IntoIterator. If the iterator yields a
value, that value is given the specified name and the body of the loop is
executed, then control returns to the head of the for loop. If the iterator
is empty, the for expression completes.
An example of a for loop over the contents of an array:
# #![allow(unused_variables)] #fn main() { let v = &["apples", "cake", "coffee"]; for text in v { println!("I like {}.", text); } #}
An example of a for loop over a series of integers:
# #![allow(unused_variables)] #fn main() { let mut sum = 0; for n in 1..11 { sum += n; } assert_eq!(sum, 55); #}
Loop labels
Syntax
LoopLabel :
LIFETIME_OR_LABEL:
A loop expression may optionally have a label. The label is written as
a lifetime preceding the loop expression, as in 'foo: loop { break 'foo; },
'bar: while false {}, 'humbug: for _ in 0..0 {}.
If a label is present, then labeled break and continue expressions nested
within this loop may exit out of this loop or return control to its head.
See break expressions and continue
expressions.
break expressions
Syntax
BreakExpression :
breakLIFETIME_OR_LABEL? Expression?
When break is encountered, execution of the associated loop body is
immediately terminated, for example:
# #![allow(unused_variables)] #fn main() { let mut last = 0; for x in 1..100 { if x > 12 { break; } last = x; } assert_eq!(last, 12); #}
A break expression is normally associated with the innermost loop, for or
while loop enclosing the break expression, but a label can
be used to specify which enclosing loop is affected. Example:
# #![allow(unused_variables)] #fn main() { 'outer: loop { while true { break 'outer; } } #}
A break expression is only permitted in the body of a loop, and has one of
the forms break, break 'label or (see below)
break EXPR or break 'label EXPR.
continue expressions
Syntax
ContinueExpression :
continueLIFETIME_OR_LABEL?
When continue is encountered, the current iteration of the associated loop
body is immediately terminated, returning control to the loop head. In
the case of a while loop, the head is the conditional expression controlling
the loop. In the case of a for loop, the head is the call-expression
controlling the loop.
Like break, continue is normally associated with the innermost enclosing
loop, but continue 'label may be used to specify the loop affected.
A continue expression is only permitted in the body of a loop.
break and loop values
When associated with a loop, a break expression may be used to return a value
from that loop, via one of the forms break EXPR or break 'label EXPR, where
EXPR is an expression whose result is returned from the loop. For example:
# #![allow(unused_variables)] #fn main() { let (mut a, mut b) = (1, 1); let result = loop { if b > 10 { break b; } let c = a + b; a = b; b = c; }; // first number in Fibonacci sequence over 10: assert_eq!(result, 13); #}
In the case a loop has an associated break, it is not considered diverging,
and the loop must have a type compatible with each break expression.
break without an expression is considered identical to break with
expression ().