]>
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. | |
52 | As discussed in with the [Iterator][iter] trait, if not specified, the `for` | |
53 | loop will apply the `into_iter` function on the collection provided to convert | |
54 | the collection into an iterator. This is not the only means to convert a | |
55 | collection into an iterator however, the other functions available include | |
56 | `iter` and `iter_mut`. | |
57 | ||
58 | These 3 functions will return different views of the data within your | |
59 | collection. | |
60 | ||
61 | * `iter` - This borrows each element of the collection through each iteration. | |
62 | Thus leaving the collection untouched and available for reuse after the loop. | |
63 | ||
64 | ```rust, editable | |
65 | fn main() { | |
66 | let names = vec!["Bob", "Frank", "Ferris"]; | |
67 | ||
68 | for name in names.iter() { | |
69 | match name { | |
70 | &"Ferris" => println!("There is a rustacean among us!"), | |
71 | _ => println!("Hello {}", name), | |
72 | } | |
73 | } | |
74 | } | |
75 | ``` | |
76 | ||
77 | * `into_iter` - This consumes the collection so that on each iteration the exact | |
78 | data is provided. Once the collection has been consumed it is no longer | |
79 | available for reuse as it has been 'moved' within the loop. | |
80 | ||
81 | ```rust, editable | |
82 | fn main() { | |
83 | let names = vec!["Bob", "Frank", "Ferris"]; | |
84 | ||
85 | for name in names.into_iter() { | |
86 | match name { | |
87 | "Ferris" => println!("There is a rustacean among us!"), | |
88 | _ => println!("Hello {}", name), | |
89 | } | |
90 | } | |
91 | } | |
92 | ``` | |
93 | ||
94 | * `iter_mut` - This mutably borrows each element of the collection, allowing for | |
95 | the collection to be modified in place. | |
96 | ||
97 | ```rust, editable | |
98 | fn main() { | |
99 | let mut names = vec!["Bob", "Frank", "Ferris"]; | |
100 | ||
101 | for name in names.iter_mut() { | |
102 | match name { | |
103 | &mut "Ferris" => println!("There is a rustacean among us!"), | |
104 | _ => println!("Hello {}", name), | |
105 | } | |
106 | } | |
107 | } | |
108 | ``` | |
109 | ||
110 | In the above snippets note the type of `match` branch, that is the key | |
532ac7d7 | 111 | difference in the types of iteration. The difference in type then of course |
2c00a5a8 XL |
112 | implies differing actions that are able to be performed. |
113 | ||
114 | ### See also | |
115 | ||
116 | [Iterator][iter] | |
117 | ||
118 | [iter]: trait/iter.html |