Iterating Collections
In this page:
for item in &collection {} // borrow
for item in &mut collection {} // mutably borrow
for item in collection {} // consume
for (i, item) in collection.iter().enumerate() {}
Iterating by Reference with iter
.iter() produces an iterator of references to each element, leaving the original collection untouched and still usable afterward.
Example: Iterating by Reference with iter
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `numbers`, set to `vec![1, 2, 3]`
let numbers = vec![1, 2, 3];
// Loop over `numbers.iter()`, binding each item to `n`
for n in numbers.iter() {
// Print "Value: {}" to the console, substituting in `n` (with a trailing newline)
println!("Value: {}", n);
}
// Print "Still usable: {:?}" to the console, substituting in `numbers` (with a trailing newline)
println!("Still usable: {:?}", numbers);
}
Login to try C/C++/Java/PHP code in the editor
Mutating in Place with iter_mut
.iter_mut() produces mutable references to each element, allowing you to modify the collection's contents directly during iteration.
Example: Mutating in Place with iter_mut
// Entry point: execution of the program starts here
fn main() {
// Declare a mutable variable `numbers`, initialized to `vec![1, 2, 3]`
let mut numbers = vec![1, 2, 3];
// Loop over `numbers.iter_mut()`, binding each item to `n`
for n in numbers.iter_mut() {
*n *= 10;
}
// Print "{:?}" to the console, substituting in `numbers` (with a trailing newline)
println!("{:?}", numbers);
}
Login to try C/C++/Java/PHP code in the editor
Taking Ownership with into_iter
Iterating a collection by value (with into_iter(), or a plain for x in collection) consumes the collection, moving each element out one at a time.
Example: Taking Ownership with into_iter
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `words`, set to `vec![String::from("a"), String::from("b")]`
let words = vec![String::from("a"), String::from("b")];
// Loop over `words.into_iter()`, binding each item to `word`
for word in words.into_iter() {
// Print "Owned word: {}" to the console, substituting in `word` (with a trailing newline)
println!("Owned word: {}", word);
}
}
Login to try C/C++/Java/PHP code in the editor
Chaining Iterator Adapters
Iterator methods like .map() and .filter() can be chained together to transform and select elements declaratively before finally collecting or summing the results.
Example: Chaining Iterator Adapters
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `numbers`, set to `vec![1, 2, 3, 4, 5]`
let numbers = vec![1, 2, 3, 4, 5];
// Declare an immutable variable `sum_of_squares` (an integer), set to `numbers.iter().map(|n| n * n).filter(|n| n % 2 == 0).sum()`
let sum_of_squares: i32 = numbers.iter().map(|n| n * n).filter(|n| n % 2 == 0).sum();
// Print "Sum of even squares: {}" to the console, substituting in `sum_of_squares` (with a trailing newline)
println!("Sum of even squares: {}", sum_of_squares);
}
Login to try C/C++/Java/PHP code in the editor
- Using
for item in collection(taking ownership) when you only meant to read the items, needing.iter()instead. - Forgetting
.iter_mut()exists for modifying every element of a collection in place during iteration. - Assuming
.iter()on aVec<T>yieldsTvalues directly, when it actually yields&Treferences.
.iter()yields immutable references to each element without taking ownership of the collection..iter_mut()yields mutable references, letting you modify elements in place during iteration.into_iter()(or a barefor x in collection) takes ownership of the collection and its elements.- Iterator adapters like
.map(),.filter(), and.sum()can be chained together to process collections declaratively.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: