-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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++) { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
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} | ||
This comment has been minimized.
Sorry, something went wrong.
nielsle
|
||
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} | ||
This comment has been minimized.
Sorry, something went wrong. |
||
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 | ||
|
||
|
1 comment
on commit 636aff1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r+
This is slightly confusing for readers that do not know C or C++. As an alternative you could write. "Here is a program that prints the numbers from 0 to 9"