]>
Commit | Line | Data |
---|---|---|
2c00a5a8 XL |
1 | # for loops |
2 | ||
3 | ## for and range | |
4 | ||
5 | The `for in` construct can be used to iterate through an `Iterator`. | |
6 | One of the easiest ways to create an iterator is to use the range | |
7 | notation `a..b`. This yields values from `a` (inclusive) to `b` | |
8 | (exclusive) in steps of one. | |
9 | ||
10 | Let's write FizzBuzz using `for` instead of `while`. | |
11 | ||
12 | ```rust,editable | |
13 | fn main() { | |
14 | // `n` will take the values: 1, 2, ..., 100 in each iteration | |
15 | for n in 1..101 { | |
16 | if n % 15 == 0 { | |
17 | println!("fizzbuzz"); | |
18 | } else if n % 3 == 0 { | |
19 | println!("fizz"); | |
20 | } else if n % 5 == 0 { | |
21 | println!("buzz"); | |
22 | } else { | |
23 | println!("{}", n); | |
24 | } | |
25 | } | |
26 | } | |
27 | ``` | |
28 | ||
83c7162d XL |
29 | Alternatively, `a..=b` can be used for a range that is inclusive on both ends. |
30 | The above can be written as: | |
31 | ||
32 | ```rust,editable | |
33 | fn main() { | |
34 | // `n` will take the values: 1, 2, ..., 100 in each iteration | |
35 | for n in 1..=100 { | |
36 | if n % 15 == 0 { | |
37 | println!("fizzbuzz"); | |
38 | } else if n % 3 == 0 { | |
39 | println!("fizz"); | |
40 | } else if n % 5 == 0 { | |
41 | println!("buzz"); | |
42 | } else { | |
43 | println!("{}", n); | |
44 | } | |
45 | } | |
46 | } | |
47 | ``` | |
48 | ||
2c00a5a8 XL |
49 | ## for and iterators |
50 | ||
51 | The `for in` construct is able to interact with an `Iterator` in several ways. | |
74b04a01 XL |
52 | As discussed in the section on the [Iterator][iter] trait, by default the `for` |
53 | loop will apply the `into_iter` function to the collection. However, this is | |
54 | not the only means of converting collections into iterators. | |
2c00a5a8 | 55 | |
74b04a01 XL |
56 | `into_iter`, `iter` and `iter_mut` all handle the conversion of a collection |
57 | into an iterator in different ways, by providing different views on the data | |
58 | within. | |
2c00a5a8 XL |
59 | |
60 | * `iter` - This borrows each element of the collection through each iteration. | |
61 | Thus leaving the collection untouched and available for reuse after the loop. | |
62 | ||
6a06907d | 63 | ```rust,editable |
2c00a5a8 XL |
64 | fn main() { |
65 | let names = vec!["Bob", "Frank", "Ferris"]; | |
66 | ||
67 | for name in names.iter() { | |
68 | match name { | |
69 | &"Ferris" => println!("There is a rustacean among us!"), | |
fc512014 | 70 | // TODO ^ Try deleting the & and matching just "Ferris" |
2c00a5a8 XL |
71 | _ => println!("Hello {}", name), |
72 | } | |
73 | } | |
fc512014 XL |
74 | |
75 | println!("names: {:?}", names); | |
2c00a5a8 XL |
76 | } |
77 | ``` | |
78 | ||
79 | * `into_iter` - This consumes the collection so that on each iteration the exact | |
80 | data is provided. Once the collection has been consumed it is no longer | |
81 | available for reuse as it has been 'moved' within the loop. | |
82 | ||
6a06907d | 83 | ```rust,editable,ignore,mdbook-runnable |
2c00a5a8 XL |
84 | fn main() { |
85 | let names = vec!["Bob", "Frank", "Ferris"]; | |
86 | ||
87 | for name in names.into_iter() { | |
88 | match name { | |
89 | "Ferris" => println!("There is a rustacean among us!"), | |
90 | _ => println!("Hello {}", name), | |
91 | } | |
92 | } | |
fc512014 XL |
93 | |
94 | println!("names: {:?}", names); | |
95 | // FIXME ^ Comment out this line | |
2c00a5a8 XL |
96 | } |
97 | ``` | |
98 | ||
99 | * `iter_mut` - This mutably borrows each element of the collection, allowing for | |
100 | the collection to be modified in place. | |
101 | ||
6a06907d | 102 | ```rust,editable |
2c00a5a8 XL |
103 | fn main() { |
104 | let mut names = vec!["Bob", "Frank", "Ferris"]; | |
105 | ||
106 | for name in names.iter_mut() { | |
48663c56 XL |
107 | *name = match name { |
108 | &mut "Ferris" => "There is a rustacean among us!", | |
109 | _ => "Hello", | |
2c00a5a8 XL |
110 | } |
111 | } | |
48663c56 XL |
112 | |
113 | println!("names: {:?}", names); | |
2c00a5a8 XL |
114 | } |
115 | ``` | |
116 | ||
117 | In the above snippets note the type of `match` branch, that is the key | |
532ac7d7 | 118 | difference in the types of iteration. The difference in type then of course |
2c00a5a8 XL |
119 | implies differing actions that are able to be performed. |
120 | ||
e1599b0c | 121 | ### See also: |
2c00a5a8 XL |
122 | |
123 | [Iterator][iter] | |
124 | ||
dc9dc135 | 125 | [iter]: ../trait/iter.md |