about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/guide.md141
1 files changed, 137 insertions, 4 deletions
diff --git a/src/doc/guide.md b/src/doc/guide.md
index d2e5d1dbd62..ce62e886b14 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -958,13 +958,146 @@ Enums
 
 ## Looping
 
-for
+Looping is the last basic construct that we haven't learned yet in Rust. Rust has
+two main looping constructs: `for` and `while`.
 
-while
+### `for`
 
-loop
+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 `for` loop:
 
-break/continue
+```{ignore,c}
+for (x = 0; x < 10; x++) {
+    printf( "%d\n", x );
+}
+```
+
+It looks like this:
+
+```{rust}
+for x in range(0i, 10i) {
+    println!("{:d}", x);
+}
+```
+
+In slightly more abstract terms,
+
+```{ignore,notrust}
+for var in expression {
+    code
+}
+```
+
+The expression is an iterator, which we will discuss in more depth later in the
+guide. 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.
+
+In our example, the `range` function is a function, provided by Rust, 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. There's an old joke that goes, "There are two hard problems in
+computer science: naming things, cache invalidation, and off-by-one errors."
+The joke, of course, being that the setup says "two hard problems" but then
+lists three things. This happens quite a bit with "C style" `for` loops.
+
+We'll talk more about `for` when we cover **vector**s, later in the Guide.
+
+### `while`
+
+The other kind of looping construct in Rust is the `while` loop. It looks like
+this:
+
+```{rust}
+let mut x = 5u;
+let mut done = false;
+
+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 {
+```
+
+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. The details of what
+that _means_ aren't super important to understand at this stage, but 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 = 5u;
+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 skip 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 = 5u;
+
+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:
+
+```
+for x in range(0i, 10i) {
+    if x % 2 == 0 { continue; }
+
+    println!("{:d}", x);
+}
+```
+
+Both `continue` and `break` are valid in both kinds of loops.
+
+We have now learned all of the most basic Rust concepts. We're ready to start
+building our guessing game, but we need to know how to do one last thing first:
+get input from the keyboard. You can't have a guessing game without the ability
+to guess!
 
 ## Guessing Game: complete