@@ -643,7 +643,7 @@ Significantly, lambda expressions _capture their environment_, which regular
643
643
[ function definitions] ( items.html#functions ) do not. The exact type of capture
644
644
depends on the [ function type] ( types.html#function-types ) inferred for the
645
645
lambda expression. In the simplest and least-expensive form (analogous to a
646
- ``` || { } `` ` expression), the lambda expression captures its environment by
646
+ ` || { } ` expression), the lambda expression captures its environment by
647
647
reference, effectively borrowing pointers to all outer variables mentioned
648
648
inside the function. Alternately, the compiler may infer that a lambda
649
649
expression should copy or move values (depending on their type) from the
@@ -668,39 +668,32 @@ let word = "konnichiwa".to_owned();
668
668
ten_times (move | j | println! (" {}, {}" , word , j ));
669
669
```
670
670
671
- ## Infinite loops
671
+ ## Loops
672
672
673
- A ` loop ` expression denotes an infinite loop.
673
+ Rust supports three loop expressions:
674
674
675
- A ` loop ` expression may optionally have a _ label_ . The label is written as
676
- a lifetime preceding the loop expression, as in ` 'foo: loop{ } ` . If a
677
- label is present, then labeled ` break ` and ` continue ` expressions nested
678
- within this loop may exit out of this loop or return control to its head.
679
- See [ break expressions] ( #break-expressions ) and [ continue
680
- expressions] ( #continue-expressions ) .
675
+ * A [ ` loop ` expression] ( #infinite-loops ) denotes an infinite loop.
676
+ * A [ ` while ` expression] ( #predicate-loops ) loops until a predicate is false.
677
+ * A [ ` for ` expression] ( #iterator-loops ) extracts values from an iterator,
678
+ looping until the iterator is empty.
681
679
682
- ## ` break ` expressions
680
+ All three types of loop support [ ` break ` expressions] ( #break-expressions ) ,
681
+ [ ` continue ` expressions] ( #continue-expressions ) , and [ labels] ( #loop-labels ) .
682
+ Only ` loop ` supports [ evaluation to non-trivial values] ( #break-and-loop-values ) .
683
683
684
- A ` break ` expression has an optional _ label_ . If the label is absent, then
685
- executing a ` break ` expression immediately terminates the innermost loop
686
- enclosing it. It is only permitted in the body of a loop. If the label is
687
- present, then ` break 'foo ` terminates the loop with label ` 'foo ` , which need not
688
- be the innermost label enclosing the ` break ` expression, but must enclose it.
684
+ ### Infinite loops
689
685
690
- ## ` continue ` expressions
686
+ A ` loop ` expression repeats execution of its body continuously:
687
+ ` loop { println!("I live."); } ` .
691
688
692
- A ` continue ` expression has an optional _ label_ . If the label is absent, then
693
- executing a ` continue ` expression immediately terminates the current iteration
694
- of the innermost loop enclosing it, returning control to the loop * head* . In
695
- the case of a ` while ` loop, the head is the conditional expression controlling
696
- the loop. In the case of a ` for ` loop, the head is the call-expression
697
- controlling the loop. If the label is present, then ` continue 'foo ` returns
698
- control to the head of the loop with label ` 'foo ` , which need not be the
699
- innermost label enclosing the ` continue ` expression, but must enclose it.
689
+ A ` loop ` expression without an associated ` break ` expression is
690
+ [ diverging] ( items.html#diverging-functions ) , and doesn't
691
+ return anything. A ` loop ` expression containing associated
692
+ [ ` break ` expression(s)] ( #break-expressions )
693
+ may terminate, and must have type compatible with the value of the ` break `
694
+ expression(s).
700
695
701
- A ` continue ` expression is only permitted in the body of a loop.
702
-
703
- ## ` while ` loops
696
+ ### Predicate loops
704
697
705
698
A ` while ` loop begins by evaluating the boolean loop conditional expression.
706
699
If the loop conditional expression evaluates to ` true ` , the loop body block
@@ -718,45 +711,112 @@ while i < 10 {
718
711
}
719
712
```
720
713
721
- Like ` loop ` expressions, ` while ` loops can be controlled with ` break ` or
722
- ` continue ` , and may optionally have a _ label_ . See [ infinite
723
- loops] ( #infinite-loops ) , [ break expressions] ( #break-expressions ) , and
724
- [ continue expressions] ( #continue-expressions ) for more information.
725
-
726
- ## ` for ` expressions
714
+ ### Iterator loops
727
715
728
716
A ` for ` expression is a syntactic construct for looping over elements provided
729
- by an implementation of ` std::iter::IntoIterator ` .
717
+ by an implementation of ` std::iter::IntoIterator ` . If the iterator yields a
718
+ value, that value is given the specified name and the body of the loop is
719
+ executed, then control returns to the head of the ` for ` loop. If the iterator
720
+ is empty, the ` for ` expression completes.
730
721
731
722
An example of a ` for ` loop over the contents of an array:
732
723
733
724
``` rust
734
- # type Foo = i32 ;
735
- # fn bar (f : & Foo ) { }
736
- # let a = 0 ;
737
- # let b = 0 ;
738
- # let c = 0 ;
739
-
740
- let v : & [Foo ] = & [a , b , c ];
725
+ let v = & [" apples" , " cake" , " coffee" ];
741
726
742
- for e in v {
743
- bar ( e );
727
+ for text in v {
728
+ println! ( " I like {}. " , text );
744
729
}
745
730
```
746
731
747
732
An example of a for loop over a series of integers:
748
733
749
734
``` rust
750
- # fn bar (b : usize ) { }
751
- for i in 0 .. 256 {
752
- bar (i );
735
+ let mut sum = 0 ;
736
+ for n in 1 .. 11 {
737
+ sum += n ;
738
+ }
739
+ assert_eq! (sum , 55 );
740
+ ```
741
+
742
+ ### Loop labels
743
+
744
+ A loop expression may optionally have a _ label_ . The label is written as
745
+ a lifetime preceding the loop expression, as in ` 'foo: loop { break 'foo; } ` ,
746
+ ` 'bar: while false {} ` , ` 'humbug: for _ in 0..0 {} ` .
747
+ If a label is present, then labeled ` break ` and ` continue ` expressions nested
748
+ within this loop may exit out of this loop or return control to its head.
749
+ See [ break expressions] ( #break-expressions ) and [ continue
750
+ expressions] ( #continue-expressions ) .
751
+
752
+ ### ` break ` expressions
753
+
754
+ When ` break ` is encountered, execution of the associated loop body is
755
+ immediately terminated, for example:
756
+
757
+ ``` rust
758
+ let mut last = 0 ;
759
+ for x in 1 .. 100 {
760
+ if x > 12 {
761
+ break ;
762
+ }
763
+ last = x ;
753
764
}
765
+ assert_eq! (last , 12 );
766
+ ```
767
+
768
+ A ` break ` expression is normally associated with the innermost ` loop ` , ` for ` or
769
+ ` while ` loop enclosing the ` break ` expression, but a [ label] ( #loop-labels ) can
770
+ be used to specify which enclosing loop is affected. Example:
771
+
772
+ ``` rust
773
+ 'outer : loop {
774
+ while true {
775
+ break 'outer ;
776
+ }
777
+ }
778
+ ```
779
+
780
+ A ` break ` expression is only permitted in the body of a loop, and has one of
781
+ the forms ` break ` , ` break 'label ` or ([ see below] ( #break-and-loop-values ) )
782
+ ` break EXPR ` or ` break 'label EXPR ` .
783
+
784
+ ### ` continue ` expressions
785
+
786
+ When ` continue ` is encountered, the current iteration of the associated loop
787
+ body is immediately terminated, returning control to the loop * head* . In
788
+ the case of a ` while ` loop, the head is the conditional expression controlling
789
+ the loop. In the case of a ` for ` loop, the head is the call-expression
790
+ controlling the loop.
791
+
792
+ Like ` break ` , ` continue ` is normally associated with the innermost enclosing
793
+ loop, but ` continue 'label ` may be used to specify the loop affected.
794
+ A ` continue ` expression is only permitted in the body of a loop.
795
+
796
+ ### ` break ` and loop values
797
+
798
+ When associated with a ` loop ` , a break expression may be used to return a value
799
+ from that loop, via one of the forms ` break EXPR ` or ` break 'label EXPR ` , where
800
+ ` EXPR ` is an expression whose result is returned from the ` loop ` . For example:
801
+
802
+ ``` rust
803
+ let (mut a , mut b ) = (1 , 1 );
804
+ let result = loop {
805
+ if b > 10 {
806
+ break b ;
807
+ }
808
+ let c = a + b ;
809
+ a = b ;
810
+ b = c ;
811
+ };
812
+ // first number in Fibonacci sequence over 10:
813
+ assert_eq! (result , 13 );
754
814
```
755
815
756
- Like ` loop ` expressions, ` for ` loops can be controlled with ` break ` or
757
- ` continue ` , and may optionally have a _ label _ . See [ infinite
758
- loops ] ( #infinite-loops ) , [ break expressions ] ( # break-expressions ) , and
759
- [ continue expressions ] ( #continue-expressions ) for more information .
816
+ In the case a ` loop ` has an associated ` break ` , it is not considered diverging,
817
+ and the ` loop ` must have a type compatible with each ` break ` expression.
818
+ ` break ` without an expression is considered identical to ` break ` with
819
+ expression ` () ` .
760
820
761
821
## ` if ` expressions
762
822
0 commit comments