← Back to Rust Course | Chapter 9: Collections | Lesson 5 of 6

Iterating Collections

Iterating means visiting each item in a list, one after another, to look at or use it.
Syntax
rust
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

markup
// 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);
}

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

markup
// 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);
}

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

markup
// 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);
    }
}

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

markup
// 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);
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using for item in collection (taking ownership) when you only meant to read the items, needing .iter() instead.
  2. Forgetting .iter_mut() exists for modifying every element of a collection in place during iteration.
  3. Assuming .iter() on a Vec<T> yields T values directly, when it actually yields &T references.
Chapter Summary
  • .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 bare for 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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.