Movatterモバイル変換


[0]ホーム

URL:


Keyboard shortcuts

Press or to navigate between chapters

PressS or/ to search in the book

Press? to show this help

PressEsc to hide this help

The Rust Reference

    Loops and other breakable expressions

    Syntax
    LoopExpression
        LoopLabel? (
            InfiniteLoopExpression
          |PredicateLoopExpression
          |IteratorLoopExpression
          |LabelBlockExpression
        )

    Rust supports four loop expressions:

    All four types of loop supportbreak expressions, andlabels.

    All except labelled block expressions supportcontinue expressions.

    Onlyloop and labelled block expressions supportevaluation to non-trivial values.

    Infinite loops

    Syntax
    InfiniteLoopExpressionloopBlockExpression

    Aloop expression repeats execution of its body continuously:loop { println!("I live."); }.

    Aloop expression without an associatedbreak expression is diverging and has type!.

    Aloop expression containing associatedbreak expression(s) may terminate, and must have type compatible with the value of thebreak expression(s).

    Predicate loops

    Awhile loop expression allows repeating the evaluation of a block while a set of conditions remain true.

    The syntax of awhile expression is a sequence of one or more condition operands separated by&&,followed by aBlockExpression.

    Condition operands must be either anExpression with aboolean type or a conditionallet match.If all of the condition operands evaluate totrue and all of thelet patterns successfully match theirscrutinees,then the loop body block executes.

    After the loop body successfully executes, the condition operands are re-evaluated to determine if the body should be executed again.

    If any condition operand evaluates tofalse or anylet pattern does not match its scrutinee,the body is not executed and execution continues after thewhile expression.

    Awhile expression evaluates to().

    An example:

    #![allow(unused)]fn main() {let mut i = 0;while i < 10 {    println!("hello");    i = i + 1;}}

    while let patterns

    let patterns in awhile condition allow binding new variables into scope when the pattern matches successfully.The following examples illustrate bindings usinglet patterns:

    #![allow(unused)]fn main() {let mut x = vec![1, 2, 3];while let Some(y) = x.pop() {    println!("y = {}", y);}while let _ = 5 {    println!("Irrefutable patterns are always true");    break;}}

    Awhile let loop is equivalent to aloop expression containing amatch expression as follows.

    'label: while let PATS = EXPR {    /* loop body */}

    is equivalent to

    'label: loop {    match EXPR {        PATS => { /* loop body */ },        _ => break,    }}

    Multiple patterns may be specified with the| operator.This has the same semantics as with| inmatch expressions:

    #![allow(unused)]fn main() {let mut vals = vec![2, 3, 1, 2, 2];while let Some(v @ 1) | Some(v @ 2) = vals.pop() {    // Prints 2, 2, then 1    println!("{}", v);}}

    while condition chains

    Multiple condition operands can be separated with&&.These have the same semantics and restrictions asif condition chains.

    The following is an example of chaining multiple expressions, mixinglet bindings and boolean expressions, and with expressions able to reference pattern bindings from previous expressions:

    fn main() {    let outer_opt = Some(Some(1i32));    while let Some(inner_opt) = outer_opt        && let Some(number) = inner_opt        && number == 1    {        println!("Peek a boo");        break;    }}

    Iterator loops

    Afor expression is a syntactic construct for looping over elements provided by an implementation ofstd::iter::IntoIterator.

    If the iterator yields a value, that value is matched against the irrefutable pattern, the body of the loop is executed, and then control returns to the head of thefor loop.If the iterator is empty, thefor expression completes.

    An example of afor loop over the contents of an array:

    #![allow(unused)]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)]fn main() {let mut sum = 0;for n in 1..11 {    sum += n;}assert_eq!(sum, 55);}

    Afor loop is equivalent to aloop expression containing amatch expression as follows:

    'label: for PATTERN in iter_expr {    /* loop body */}

    is equivalent to

    {    let result = match IntoIterator::into_iter(iter_expr) {        mut iter => 'label: loop {            let mut next;            match Iterator::next(&mut iter) {                Option::Some(val) => next = val,                Option::None => break,            };            let PATTERN = next;            let () = { /* loop body */ };        },    };    result}

    IntoIterator,Iterator, andOption are always the standard library items here, not whatever those names resolve to in the current scope.

    The variable namesnext,iter, andval are for exposition only, they do not actually have names the user can type.

    Note

    The outermatch is used to ensure that anytemporary values initer_expr don’t get dropped before the loop is finished.next is declared before being assigned because it results in types being inferred correctly more often.

    Loop labels

    Syntax
    LoopLabelLIFETIME_OR_LABEL:

    A loop expression may optionally have alabel. 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 labeledbreak andcontinue expressions nested within this loop may exit out of this loop or return control to its head.Seebreak expressions andcontinue expressions.

    Labels follow the hygiene and shadowing rules of local variables. For example, this code will print “outer loop”:

    #![allow(unused)]fn main() {'a: loop {    'a: loop {        break 'a;    }    print!("outer loop");    break 'a;}}

    '_ is not a valid loop label.

    break expressions

    Syntax
    BreakExpressionbreakLIFETIME_OR_LABEL?Expression?

    Whenbreak is encountered, execution of the associated loop body is immediately terminated, for example:

    #![allow(unused)]fn main() {let mut last = 0;for x in 1..100 {    if x > 12 {        break;    }    last = x;}assert_eq!(last, 12);}

    Abreak expression is normally associated with the innermostloop,for orwhile loop enclosing thebreak expression,but alabel can be used to specify which enclosing loop is affected.Example:

    #![allow(unused)]fn main() {'outer: loop {    while true {        break 'outer;    }}}

    Abreak expression is only permitted in the body of a loop, and has one of the formsbreak,break 'label or (see below)break EXPR orbreak 'label EXPR.

    Labelled block expressions

    Labelled block expressions are exactly like block expressions, except that they allow usingbreak expressions within the block.

    Unlike loops,break expressions within a labelled block expressionmust have a label (i.e. the label is not optional).

    Similarly, labelled block expressionsmust begin with a label.

    #![allow(unused)]fn main() {fn do_thing() {}fn condition_not_met() -> bool { true }fn do_next_thing() {}fn do_last_thing() {}let result = 'block: {    do_thing();    if condition_not_met() {        break 'block 1;    }    do_next_thing();    if condition_not_met() {        break 'block 2;    }    do_last_thing();    3};}

    continue expressions

    Syntax
    ContinueExpressioncontinueLIFETIME_OR_LABEL?

    Whencontinue is encountered, the current iteration of the associated loop body is immediately terminated, returning control to the loophead.

    In the case of awhile loop, the head is the conditional operands controlling the loop.

    In the case of afor loop, the head is the call-expression controlling the loop.

    Likebreak,continue is normally associated with the innermost enclosing loop, butcontinue 'label may be used to specify the loop affected.

    Acontinue expression is only permitted in the body of a loop.

    break and loop values

    When associated with aloop, a break expression may be used to return a value from that loop, via one of the formsbreak EXPR orbreak 'label EXPR, whereEXPR is an expression whose result is returned from theloop.For example:

    #![allow(unused)]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 aloop has an associatedbreak, it is not considered diverging, and theloop must have a type compatible with eachbreak expression.break without an expression is considered identical tobreak with expression().


    [8]ページ先頭

    ©2009-2025 Movatter.jp