Consider a range of numbers—0, 1, 2. A for
-loop can step through this range, with minimal syntax and clear code in Rust.
Is the for
-loop supposed to include, or exclude the second number in the range? We can do both with special Rust syntax.
This program uses the most common, and probably clearest, syntax for iteration in Rust. It starts at a number, and ends when a second number is reached.
fn main() { // Loop over first 3 numbers. // ... The top bounds is exclusive (not included). for i in 0..3 { println!("Hello: {}", i) } }Hello: 0 Hello: 1 Hello: 2
Sometimes, like when looping up the maximum integer value in a type, we want to include the second number. We can use the equals sign in the range for this.
i32
type. We use the i32
MAX constant to avoid having to type out the entire number.fn main() { // Loop over last 4 numbers in the i32 type. // ... Use "=" in range to include that number. // Use "i32::MAX." for i in i32::MAX - 3..=i32::MAX { println!("I: {}", i) } }I: 2147483644 I: 2147483645 I: 2147483646 I: 2147483647
We can use a for-in
loop over a vector or slice. Here we create a vector and push 3 integers to it. Then we use it in 2 for
-loops, one after the other.
for
-loop so that it is not moved into the loop.for
-loop, it would become unavailable for later use.for-in
loop but do not care about the elements, we can use an underscore "_" to eliminate compiler warnings.fn main() { let mut values = vec![]; values.push(10); values.push(20); values.push(30); // Use for-loop over values. // Borrow the vector so we can use it in the next loop. for value in &values { println!("VALUE: {}", value); } // We can ignore the iteration variable if we want. for _ in &values { println!("ITERATION"); } }VALUE: 10 VALUE: 20 VALUE: 30 ITERATION ITERATION ITERATION
Consider the for-in
loop: we may often want to get both the element value at each index, and the index itself. We can use enumerate()
to get these 2-value pairs.
enumerate()
on the result of iter()
. We can get the 2 values from the tuple directly in the for
-loop.str
array, alongside the 3 indexes (0, 1 and 2).fn main() { let items = ["chair", "computer", "screen"]; // Use enumerate to get an index and value for each element. for (i, item) in items.iter().enumerate() { println!("ITEM: {} = {}", i, item); } }ITEM: 0 = chair ITEM: 1 = computer ITEM: 2 = screen
Reverse
To loop in reverse, we can get the iterator with iter()
and then call rev()
. This starts at the last element, and proceeds to the first.
fn main() { let items = vec![10, 20, 30, 40]; // Loop over items in reverse. for item in items.iter().rev() { println!("ITEM: {item}"); } }ITEM: 40 ITEM: 30 ITEM: 20 ITEM: 10
In programs we often need to iterate over every character in a string
. With for, we can do this in Rust—we can avoid some bugs easily this way.
Suppose we are looping over a range of i32
values, but want to access a Vec
or slice with the value. We must cast to a usize
in Rust.
For
-loops are clear and easy-to-use in Rust. One important trick is the inclusive end value in range—the equals sign is part of the range.