From b36551b0e2cecaef8908cb11b63aff1256a377f5 Mon Sep 17 00:00:00 2001 From: Kieran Hunt Date: Sun, 26 Jul 2015 19:39:32 +0200 Subject: [PATCH 1/4] Adding docs for loops and loop labels. --- src/doc/trpl/SUMMARY.md | 1 + src/doc/trpl/infinite-loops.md | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/doc/trpl/infinite-loops.md diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index 85f0019276eef..c2afae7147646 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -26,6 +26,7 @@ * [Primitive Types](primitive-types.md) * [Comments](comments.md) * [if](if.md) + * [infinite loops](infinite-loops.md) * [for loops](for-loops.md) * [while loops](while-loops.md) * [Ownership](ownership.md) diff --git a/src/doc/trpl/infinite-loops.md b/src/doc/trpl/infinite-loops.md new file mode 100644 index 0000000000000..948249e924cf5 --- /dev/null +++ b/src/doc/trpl/infinite-loops.md @@ -0,0 +1,40 @@ +% infinite loops + +The infinite `loop` is the simplest form of `loop` available in Rust. Using the keyword `loop`, Rust provides a way to loop until a `break` or `return` is issued. Rust's infinite `loop`s look like this: + +``` +loop { + println!("Loop forever!"); +} +``` + +Leaving a infinite `loop` can be achieved using a break statement as follows: + +``` +let mut i = 0; +loop { + if i == 10 { + break; + } + println!("Loop number {}", i); + i = i + 1; +} +``` + +## Loop labels + +Labels can be assigned to `loop`s to so that, in the case of nested `loop`s, an outer `loop` may be left early when certain criteria are met in an inner `loop`. + +``` +let mut i = 0; +'outer: loop { + 'inner: loop { + if i == 10 { + break 'outer; + } + i = i + 1; + } +} +``` + +In the above example, the inner `loop` is able to cause the outer `loop` to stop. From a3872a3685471ea426b3803054d1d13c87939fa6 Mon Sep 17 00:00:00 2001 From: Kieran Hunt Date: Wed, 29 Jul 2015 22:38:43 +0200 Subject: [PATCH 2/4] Consolidating loop information to a single page. Per PR #27305 --- src/doc/trpl/SUMMARY.md | 4 +- src/doc/trpl/for-loops.md | 85 -------------- src/doc/trpl/infinite-loops.md | 6 +- src/doc/trpl/loops.md | 209 +++++++++++++++++++++++++++++++++ src/doc/trpl/while-loops.md | 111 ----------------- 5 files changed, 213 insertions(+), 202 deletions(-) delete mode 100644 src/doc/trpl/for-loops.md create mode 100644 src/doc/trpl/loops.md delete mode 100644 src/doc/trpl/while-loops.md diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index c2afae7147646..24686e772e3c3 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -26,9 +26,7 @@ * [Primitive Types](primitive-types.md) * [Comments](comments.md) * [if](if.md) - * [infinite loops](infinite-loops.md) - * [for loops](for-loops.md) - * [while loops](while-loops.md) + * [Loops](loops.md) * [Ownership](ownership.md) * [References and Borrowing](references-and-borrowing.md) * [Lifetimes](lifetimes.md) diff --git a/src/doc/trpl/for-loops.md b/src/doc/trpl/for-loops.md deleted file mode 100644 index 2866cee3a1a63..0000000000000 --- a/src/doc/trpl/for-loops.md +++ /dev/null @@ -1,85 +0,0 @@ -% for Loops - -The `for` loop is used to loop a particular number of times. Rust’s `for` loops -work a bit differently than in other systems languages, however. Rust’s `for` -loop doesn’t look like this “C-style” `for` loop: - -```c -for (x = 0; x < 10; x++) { - printf( "%d\n", x ); -} -``` - -Instead, it looks like this: - -```rust -for x in 0..10 { - println!("{}", x); // x: i32 -} -``` - -In slightly more abstract terms, - -```ignore -for var in expression { - code -} -``` - -The expression is an [iterator][iterator]. The iterator gives back a series of -elements. Each element is one iteration of the loop. That value is then bound -to the name `var`, which is valid for the loop body. Once the body is over, the -next value is fetched from the iterator, and we loop another time. When there -are no more values, the `for` loop is over. - -[iterator]: iterators.html - -In our example, `0..10` is an expression that takes a start and an end position, -and gives an iterator over those values. The upper bound is exclusive, though, -so our loop will print `0` through `9`, not `10`. - -Rust does not have the “C-style” `for` loop on purpose. Manually controlling -each element of the loop is complicated and error prone, even for experienced C -developers. - -# Enumerate - -When you need to keep track of how many times you already looped, you can use the `.enumerate()` function. - -## On ranges: - -```rust -for (i,j) in (5..10).enumerate() { - println!("i = {} and j = {}", i, j); -} -``` - -Outputs: - -```text -i = 0 and j = 5 -i = 1 and j = 6 -i = 2 and j = 7 -i = 3 and j = 8 -i = 4 and j = 9 -``` - -Don't forget to add the parentheses around the range. - -## On iterators: - -```rust -# let lines = "hello\nworld".lines(); -for (linenumber, line) in lines.enumerate() { - println!("{}: {}", linenumber, line); -} -``` - -Outputs: - -```text -0: Content of line one -1: Content of line two -2: Content of line tree -3: Content of line four -``` diff --git a/src/doc/trpl/infinite-loops.md b/src/doc/trpl/infinite-loops.md index 948249e924cf5..823b3b44885ae 100644 --- a/src/doc/trpl/infinite-loops.md +++ b/src/doc/trpl/infinite-loops.md @@ -2,7 +2,7 @@ The infinite `loop` is the simplest form of `loop` available in Rust. Using the keyword `loop`, Rust provides a way to loop until a `break` or `return` is issued. Rust's infinite `loop`s look like this: -``` +```rust loop { println!("Loop forever!"); } @@ -10,7 +10,7 @@ loop { Leaving a infinite `loop` can be achieved using a break statement as follows: -``` +```rust let mut i = 0; loop { if i == 10 { @@ -25,7 +25,7 @@ loop { Labels can be assigned to `loop`s to so that, in the case of nested `loop`s, an outer `loop` may be left early when certain criteria are met in an inner `loop`. -``` +```rust let mut i = 0; 'outer: loop { 'inner: loop { diff --git a/src/doc/trpl/loops.md b/src/doc/trpl/loops.md new file mode 100644 index 0000000000000..91ff832a19a51 --- /dev/null +++ b/src/doc/trpl/loops.md @@ -0,0 +1,209 @@ +% Loops + +Rust currently provides three approaches to performing some kind of iterative activity. They are: `loop`, `while` and `for`. Each approach has its own set of uses. + +## loop + +The infinite `loop` is the simplest form of loop available in Rust. Using the keyword `loop`, Rust provides a way to loop indefinitely until some terminating statement is reached. Rust's infinite `loop`s look like this: + +```rust +loop { + println!("Loop forever!"); +} +``` + +## while + +Rust also has a `while` loop. It looks like this: + +```rust +let mut x = 5; // mut x: i32 +let mut done = false; // mut done: bool + +while !done { + x += x - 3; + + println!("{}", x); + + if x % 5 == 0 { + done = true; + } +} +``` + +`while` loops are the correct choice when you’re not sure how many times +you need to loop. + +If you need an infinite loop, you may be tempted to write this: + +```rust,ignore +while true { +``` + +However, `loop` is far better suited to handle this case: + +```rust,ignore +loop { +``` + +Rust’s control-flow analysis treats this construct differently than a `while +true`, since we know that it will always loop. In general, the more information +we can give to the compiler, the better it can do with safety and code +generation, so you should always prefer `loop` when you plan to loop +infinitely. + +## for + +The `for` loop is used to loop a particular number of times. Rust’s `for` loops +work a bit differently than in other systems languages, however. Rust’s `for` +loop doesn’t look like this “C-style” `for` loop: + +```c +for (x = 0; x < 10; x++) { + printf( "%d\n", x ); +} +``` + +Instead, it looks like this: + +```rust +for x in 0..10 { + println!("{}", x); // x: i32 +} +``` + +In slightly more abstract terms, + +```ignore +for var in expression { + code +} +``` + +The expression is an [iterator][iterator]. The iterator gives back a series of +elements. Each element is one iteration of the loop. That value is then bound +to the name `var`, which is valid for the loop body. Once the body is over, the +next value is fetched from the iterator, and we loop another time. When there +are no more values, the `for` loop is over. + +[iterator]: iterators.html + +In our example, `0..10` is an expression that takes a start and an end position, +and gives an iterator over those values. The upper bound is exclusive, though, +so our loop will print `0` through `9`, not `10`. + +Rust does not have the “C-style” `for` loop on purpose. Manually controlling +each element of the loop is complicated and error prone, even for experienced C +developers. + +### Enumerate + +When you need to keep track of how many times you already looped, you can use the `.enumerate()` function. + +#### On ranges: + +```rust +for (i,j) in (5..10).enumerate() { + println!("i = {} and j = {}", i, j); +} +``` + +Outputs: + +```text +i = 0 and j = 5 +i = 1 and j = 6 +i = 2 and j = 7 +i = 3 and j = 8 +i = 4 and j = 9 +``` + +Don't forget to add the parentheses around the range. + +#### On iterators: + +```rust +# let lines = "hello\nworld".lines(); +for (linenumber, line) in lines.enumerate() { + println!("{}: {}", linenumber, line); +} +``` + +Outputs: + +```text +0: Content of line one +1: Content of line two +2: Content of line tree +3: Content of line four +``` + +## Ending iteration early + +Let’s take a look at that `while` loop we had earlier: + +```rust +let mut x = 5; +let mut done = false; + +while !done { + x += x - 3; + + println!("{}", x); + + if x % 5 == 0 { + done = true; + } +} +``` + +We had to keep a dedicated `mut` boolean variable binding, `done`, to know +when we should exit out of the loop. Rust has two keywords to help us with +modifying iteration: `break` and `continue`. + +In this case, we can write the loop in a better way with `break`: + +```rust +let mut x = 5; + +loop { + x += x - 3; + + println!("{}", x); + + if x % 5 == 0 { break; } +} +``` + +We now loop forever with `loop` and use `break` to break out early. Issuing an explicit `return` statement will also serve to terminate the loop early. + +`continue` is similar, but instead of ending the loop, goes to the next +iteration. This will only print the odd numbers: + +```rust +for x in 0..10 { + if x % 2 == 0 { continue; } + + println!("{}", x); +} +``` + +## Loop labels + +You may also encounter situations where you have nested loops and need to +specify which one your `break` or `continue` statement is for. Like most +other languages, by default a `break` or `continue` will apply to innermost +loop. In a sitation where you would like to a `break` or `continue` for one +of the outer loops, you can use labels to specify which loop the `break` or + `continue` statement applies to. This will only print when both `x` and `y` are + odd: + +```rust +'outer: for x in 0..10 { + 'inner: for y in 0..10 { + if x % 2 == 0 { continue 'outer; } // continues the loop over x + if y % 2 == 0 { continue 'inner; } // continues the loop over y + println!("x: {}, y: {}", x, y); + } +} +``` diff --git a/src/doc/trpl/while-loops.md b/src/doc/trpl/while-loops.md deleted file mode 100644 index 124ebc7d69ddc..0000000000000 --- a/src/doc/trpl/while-loops.md +++ /dev/null @@ -1,111 +0,0 @@ -% while Loops - -Rust also has a `while` loop. It looks like this: - -```rust -let mut x = 5; // mut x: i32 -let mut done = false; // mut done: bool - -while !done { - x += x - 3; - - println!("{}", x); - - if x % 5 == 0 { - done = true; - } -} -``` - -`while` loops are the correct choice when you’re not sure how many times -you need to loop. - -If you need an infinite loop, you may be tempted to write this: - -```rust,ignore -while true { -``` - -However, Rust has a dedicated keyword, `loop`, to handle this case: - -```rust,ignore -loop { -``` - -Rust’s control-flow analysis treats this construct differently than a `while -true`, since we know that it will always loop. In general, the more information -we can give to the compiler, the better it can do with safety and code -generation, so you should always prefer `loop` when you plan to loop -infinitely. - -## Ending iteration early - -Let’s take a look at that `while` loop we had earlier: - -```rust -let mut x = 5; -let mut done = false; - -while !done { - x += x - 3; - - println!("{}", x); - - if x % 5 == 0 { - done = true; - } -} -``` - -We had to keep a dedicated `mut` boolean variable binding, `done`, to know -when we should exit out of the loop. Rust has two keywords to help us with -modifying iteration: `break` and `continue`. - -In this case, we can write the loop in a better way with `break`: - -```rust -let mut x = 5; - -loop { - x += x - 3; - - println!("{}", x); - - if x % 5 == 0 { break; } -} -``` - -We now loop forever with `loop` and use `break` to break out early. - -`continue` is similar, but instead of ending the loop, goes to the next -iteration. This will only print the odd numbers: - -```rust -for x in 0..10 { - if x % 2 == 0 { continue; } - - println!("{}", x); -} -``` - -You may also encounter situations where you have nested loops and need to -specify which one your `break` or `continue` statement is for. Like most -other languages, by default a `break` or `continue` will apply to innermost -loop. In a sitation where you would like to a `break` or `continue` for one -of the outer loops, you can use labels to specify which loop the `break` or - `continue` statement applies to. This will only print when both `x` and `y` are - odd: - -```rust -'outer: for x in 0..10 { - 'inner: for y in 0..10 { - if x % 2 == 0 { continue 'outer; } // continues the loop over x - if y % 2 == 0 { continue 'inner; } // continues the loop over y - println!("x: {}, y: {}", x, y); - } -} -``` - -Both `continue` and `break` are valid in both `while` loops and [`for` loops][for]. - -[for]: for-loops.html From 4a5194a6d568644d40f6fa4dd2d5356c581eeb84 Mon Sep 17 00:00:00 2001 From: Kieran Hunt Date: Thu, 30 Jul 2015 07:22:21 +0200 Subject: [PATCH 3/4] Removing infinite loops file --- src/doc/trpl/infinite-loops.md | 40 ---------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 src/doc/trpl/infinite-loops.md diff --git a/src/doc/trpl/infinite-loops.md b/src/doc/trpl/infinite-loops.md deleted file mode 100644 index 823b3b44885ae..0000000000000 --- a/src/doc/trpl/infinite-loops.md +++ /dev/null @@ -1,40 +0,0 @@ -% infinite loops - -The infinite `loop` is the simplest form of `loop` available in Rust. Using the keyword `loop`, Rust provides a way to loop until a `break` or `return` is issued. Rust's infinite `loop`s look like this: - -```rust -loop { - println!("Loop forever!"); -} -``` - -Leaving a infinite `loop` can be achieved using a break statement as follows: - -```rust -let mut i = 0; -loop { - if i == 10 { - break; - } - println!("Loop number {}", i); - i = i + 1; -} -``` - -## Loop labels - -Labels can be assigned to `loop`s to so that, in the case of nested `loop`s, an outer `loop` may be left early when certain criteria are met in an inner `loop`. - -```rust -let mut i = 0; -'outer: loop { - 'inner: loop { - if i == 10 { - break 'outer; - } - i = i + 1; - } -} -``` - -In the above example, the inner `loop` is able to cause the outer `loop` to stop. From a989ed8880ee63df120c2e2cd073e41e6beed4e3 Mon Sep 17 00:00:00 2001 From: Kieran Hunt Date: Sat, 1 Aug 2015 22:02:00 +0200 Subject: [PATCH 4/4] Adding an ignore annotation to an infinite loop so that it wont hang the tester. --- src/doc/trpl/loops.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/loops.md b/src/doc/trpl/loops.md index 91ff832a19a51..a91fb8dadafb4 100644 --- a/src/doc/trpl/loops.md +++ b/src/doc/trpl/loops.md @@ -6,7 +6,7 @@ Rust currently provides three approaches to performing some kind of iterative ac The infinite `loop` is the simplest form of loop available in Rust. Using the keyword `loop`, Rust provides a way to loop indefinitely until some terminating statement is reached. Rust's infinite `loop`s look like this: -```rust +```rust,ignore loop { println!("Loop forever!"); }