blob: f457529df60253f559fff159212fdf11b0955d18 [file] [log] [blame] [view] [edit]
# for loops
## for and range
The `for in` construct can be used to iterate through an `Iterator`.
One of the easiest ways to create an iterator is to use the range
notation `a..b`. This yields values from `a` (inclusive) to `b`
(exclusive) in steps of one.
Let's write FizzBuzz using `for` instead of `while`.
```rust,editable
fn main() {
// `n` will take the values: 1, 2, ..., 100 in each iteration
for n in 1..101 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
}
}
```
Alternatively, `a..=b` can be used for a range that is inclusive on both ends.
The above can be written as:
```rust,editable
fn main() {
// `n` will take the values: 1, 2, ..., 100 in each iteration
for n in 1..=100 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
}
}
```
## for and iterators
The `for in` construct is able to interact with an `Iterator` in several ways.
As discussed in the section on the [Iterator][iter] trait, by default the `for`
loop will apply the `into_iter` function to the collection. However, this is
not the only means of converting collections into iterators.
`into_iter`, `iter` and `iter_mut` all handle the conversion of a collection
into an iterator in different ways, by providing different views on the data
within.
* `iter` - This borrows each element of the collection through each iteration.
Thus leaving the collection untouched and available for reuse after the loop.
```rust,editable
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter() {
match name {
&"Ferris" => println!("There is a rustacean among us!"),
// TODO ^ Try deleting the & and matching just "Ferris"
_ => println!("Hello {}", name),
}
}
println!("names: {:?}", names);
}
```
* `into_iter` - This consumes the collection so that on each iteration the exact
data is provided. Once the collection has been consumed it is no longer
available for reuse as it has been 'moved' within the loop.
```rust,editable,ignore,mdbook-runnable
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.into_iter() {
match name {
"Ferris" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
}
println!("names: {:?}", names);
// FIXME ^ Comment out this line
}
```
* `iter_mut` - This mutably borrows each element of the collection, allowing for
the collection to be modified in place.
```rust,editable
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
*name = match name {
&mut "Ferris" => "There is a rustacean among us!",
_ => "Hello",
}
}
println!("names: {:?}", names);
}
```
In the above snippets note the type of `match` branch, that is the key
difference in the types of iteration. The difference in type then of course
implies differing actions that are able to be performed.
### See also:
[Iterator][iter]
[iter]: ../trait/iter.md