@@ -589,52 +589,32 @@ let word = "konnichiwa".to_owned();
589
589
ten_times (move | j | println! (" {}, {}" , word , j ));
590
590
```
591
591
592
- ## Infinite loops
592
+ ## Loops
593
593
594
- A ` loop ` expression denotes an infinite loop.
594
+ Rust supports three loop expressions:
595
595
596
- A ` loop ` expression may optionally have a _ label_ . The label is written as
597
- a lifetime preceding the loop expression, as in ` 'foo: loop{ } ` . If a
598
- label is present, then labeled ` break ` and ` continue ` expressions nested
599
- within this loop may exit out of this loop or return control to its head.
600
- See [ break expressions] ( #break-expressions ) and [ continue
601
- expressions] ( #continue-expressions ) .
596
+ * A [ ` loop ` expression] ( #infinite-loops ) denotes an infinite loop.
597
+ * A [ ` while ` expression] ( #predicate-loops ) loops until a predicate is false.
598
+ * A [ ` for ` expression] ( #iterator-loops ) extracts values from an iterator,
599
+ looping until the iterator is empty.
602
600
603
- A ` loop ` expression is [ diverging] ( items.html#diverging-functions ) , and doesn't
604
- return anything. However, when it contains a [ break
605
- expression] ( #break-expressions ) , it returns the value attached to the ` break `
606
- that caused the loop to stop.
601
+ All three types of loop support [ ` break ` expressions] ( #break-expressions ) ,
602
+ [ ` continue ` expressions] ( #continue-expressions ) , and [ labels] ( #loop-labels ) .
603
+ Only ` loop ` supports [ break-with-value] ( #break-with-value ) .
607
604
608
- ## ` break ` expressions
605
+ ### Infinite loops
609
606
610
- A ` break ` expression has an optional _ label_ . If the label is absent, then
611
- executing a ` break ` expression immediately terminates the innermost loop
612
- enclosing it. It is only permitted in the body of a loop. If the label is
613
- present, then ` break 'foo ` terminates the loop with label ` 'foo ` , which need not
614
- be the innermost label enclosing the ` break ` expression, but must enclose it.
607
+ A ` loop ` expression repeats execution of its body continuously:
608
+ ` loop { println!("I live."); } ` .
615
609
616
- When the ` break ` expression is enclosed in a ` loop ` it has an optional return
617
- value attached which will be returned by the loop ended by the
618
- expression. When it's not provided it defaults to ` () ` .
610
+ A ` loop ` expression without an associated ` break ` expression is
611
+ [ diverging] ( items.html#diverging-functions ) , and doesn't
612
+ return anything. A ` loop ` expression containing associated
613
+ [ ` break ` expression(s)] ( #break-expressions )
614
+ may terminate, and must have type compatible with the value of the ` break `
615
+ expression(s).
619
616
620
- If both a label and a return value are present in the expression, the label
621
- must be placed before the return value. For example ` break 'label 42 ` breaks
622
- the loop labelled ` 'label ` , returning ` 42 ` from it.
623
-
624
- ## ` continue ` expressions
625
-
626
- A ` continue ` expression has an optional _ label_ . If the label is absent, then
627
- executing a ` continue ` expression immediately terminates the current iteration
628
- of the innermost loop enclosing it, returning control to the loop * head* . In
629
- the case of a ` while ` loop, the head is the conditional expression controlling
630
- the loop. In the case of a ` for ` loop, the head is the call-expression
631
- controlling the loop. If the label is present, then ` continue 'foo ` returns
632
- control to the head of the loop with label ` 'foo ` , which need not be the
633
- innermost label enclosing the ` continue ` expression, but must enclose it.
634
-
635
- A ` continue ` expression is only permitted in the body of a loop.
636
-
637
- ## ` while ` loops
617
+ ### Predicate loops
638
618
639
619
A ` while ` loop begins by evaluating the boolean loop conditional expression.
640
620
If the loop conditional expression evaluates to ` true ` , the loop body block
@@ -652,45 +632,113 @@ while i < 10 {
652
632
}
653
633
```
654
634
655
- Like ` loop ` expressions, ` while ` loops can be controlled with ` break ` or
656
- ` continue ` , and may optionally have a _ label_ . See [ infinite
657
- loops] ( #infinite-loops ) , [ break expressions] ( #break-expressions ) , and
658
- [ continue expressions] ( #continue-expressions ) for more information.
659
-
660
- ## ` for ` expressions
635
+ ### Iterator loops
661
636
662
637
A ` for ` expression is a syntactic construct for looping over elements provided
663
- by an implementation of ` std::iter::IntoIterator ` .
638
+ by an implementation of ` std::iter::IntoIterator ` . If the iterator yields a
639
+ value, that value is given the specified name and the body of the loop is
640
+ executed, then control returns to the head of the ` for ` loop. If the iterator
641
+ is empty, the ` for ` expression completes.
664
642
665
643
An example of a ` for ` loop over the contents of an array:
666
644
667
645
``` rust
668
- # type Foo = i32 ;
669
- # fn bar (f : & Foo ) { }
670
- # let a = 0 ;
671
- # let b = 0 ;
672
- # let c = 0 ;
646
+ let v = & [" apples" , " cake" , " coffee" ];
673
647
674
- let v : & [Foo ] = & [a , b , c ];
675
-
676
- for e in v {
677
- bar (e );
648
+ for text in v {
649
+ println! (" I like {}." , text );
678
650
}
679
651
```
680
652
681
653
An example of a for loop over a series of integers:
682
654
683
655
``` rust
684
- # fn bar (b : usize ) { }
685
- for i in 0 .. 256 {
686
- bar (i );
656
+ let mut sum = 0 ;
657
+ for n in 1 .. 11 {
658
+ sum += n ;
659
+ }
660
+ assert_eq! (sum , 55 );
661
+ ```
662
+
663
+ ### Loop labels
664
+
665
+ A loop expression may optionally have a _ label_ . The label is written as
666
+ a lifetime preceding the loop expression, as in ` 'foo: loop { break 'foo; } ` ,
667
+ ` 'bar: while false {} ` , ` 'humbug: for _ in 0..0 {} ` .
668
+ If a label is present, then labeled ` break ` and ` continue ` expressions nested
669
+ within this loop may exit out of this loop or return control to its head.
670
+ See [ break expressions] ( #break-expressions ) and [ continue
671
+ expressions] ( #continue-expressions ) .
672
+
673
+ ### ` break ` expressions
674
+
675
+ When ` break ` is encountered, execution of the associated loop body is
676
+ immediately terminated, for example:
677
+
678
+ ``` rust
679
+ let mut last = 0 ;
680
+ for x in 1 .. 100 {
681
+ if x > 12 {
682
+ break ;
683
+ }
684
+ last = x ;
687
685
}
686
+ assert_eq! (last , 12 );
687
+ ```
688
+
689
+ A ` break ` expression is normally associated with the innermost ` loop ` , ` for ` or
690
+ ` while ` loop enclosing the ` break ` expression, but a [ label] ( #loop-labels ) can
691
+ be used to specify which enclosing loop is affected. Example:
692
+
693
+ ``` rust
694
+ 'outer : loop {
695
+ while true {
696
+ break 'outer ;
697
+ }
698
+ }
699
+ ```
700
+
701
+ A ` break ` expression is only permitted in the body of a loop, and has one of
702
+ the forms ` break ` , ` break 'label ` or (see [ break-with-value] ( #break-with-value ) )
703
+ ` break EXPR ` or ` break 'label EXPR ` .
704
+
705
+ ### ` continue ` expressions
706
+
707
+ When ` continue ` is encountered, the current iteration of the associated loop
708
+ body is immediately terminated, returning control to the loop * head* . In
709
+ the case of a ` while ` loop, the head is the conditional expression controlling
710
+ the loop. In the case of a ` for ` loop, the head is the call-expression
711
+ controlling the loop.
712
+
713
+ Like ` break ` , ` continue ` is normally associated with the innermost enclosing
714
+ loop, but ` continue 'label ` may be used to specify the loop affected.
715
+ A ` continue ` expression is only permitted in the body of a loop.
716
+
717
+ ### Break-with-value
718
+
719
+ When associated with a ` loop ` , a break expression may be used to return a value
720
+ from that loop, via one of the forms ` break EXPR ` or ` break 'label EXPR ` , where
721
+ ` EXPR ` is an expression whose result is returned from the ` loop ` . For example:
722
+
723
+ ``` rust
724
+ #![feature(loop_break_value)]
725
+ let (mut a , mut b ) = (1 , 1 );
726
+ let result = loop {
727
+ if b > 10 {
728
+ break b ;
729
+ }
730
+ let c = a + b ;
731
+ a = b ;
732
+ b = c ;
733
+ };
734
+ // first number in Fibonacci sequence over 10:
735
+ assert_eq! (result , 13 );
688
736
```
689
737
690
- Like ` loop ` expressions, ` for ` loops can be controlled with ` break ` or
691
- ` continue ` , and may optionally have a _ label _ . See [ infinite
692
- loops ] ( #infinite-loops ) , [ break expressions ] ( # break-expressions ) , and
693
- [ continue expressions ] ( #continue-expressions ) for more information .
738
+ In the case a ` loop ` has an associated ` break ` , it is not considered diverging,
739
+ and the ` loop ` must have a type compatible with each ` break ` expression.
740
+ ` break ` without an expression is considered identical to ` break ` with
741
+ expression ` () ` .
694
742
695
743
## ` if ` expressions
696
744
0 commit comments