Nugget 9

Home

What Is an Iterator?

You write for x in vec and it just works. But what's actually happening? An iterator is anything that knows how to produce items one at a time — and nearly everything in Rust can become one.

The Iterator Trait

At its core, an iterator is anything that implements this trait:

trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

That's it. One method, next(). It returns:

let v = vec![10, 20, 30];
let mut iter = v.iter();  // get an iterator

assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.next(), Some(&20));
assert_eq!(iter.next(), Some(&30));
assert_eq!(iter.next(), None);     // end of the road

The for Loop Is Sugar

Every for loop is secretly a call to .next():

// What you write:
for item in &v {
    println!("{item}");
}

// What the compiler generates:
let mut iter = v.iter();
while let Some(item) = iter.next() {
    println!("{item}");
}

The while let Some pattern is idiomatic Rust — it unwraps the Option and exits the loop when None is returned.

Three Ways to Iterate

A Vec can produce three different kinds of iterators depending on how you access it:

let v = vec!["a".to_string(), "b".to_string(), "c".to_string()];

// 1. Immutable borrow — gives &T
for item in &v {         // calls v.iter()
    println!("{item}");   // item: &String
}
println!("v is still usable: {:?}", v);

// 2. Mutable borrow — gives &mut T
for item in &mut v {      // calls v.iter_mut()
    item.push_str("!");
}
println!("v now: {:?}", v);

// 3. Consume — gives T, v is gone
for item in v {            // calls v.into_iter()
    println!("{item}");    // item: String (owned)
}
// println!("{:?}", v);    // ❌ v was moved!
Loop syntax Method Yields Original usable?
for x in &v iter() &T ✅ Yes
for x in &mut v iter_mut() &mut T ✅ Yes (after borrow ends)
for x in v into_iter() T (owned) ❌ No, consumed

It's Not Just Vec

Ranges, strings, slices, HashMap, files — they all produce iterators:

// Range
for i in 0..5 { println!("{i}"); }        // 0 1 2 3 4

// String chars
for c in "hello".chars() { print!("{c} "); } // h e l l o

// Array slice
let arr = [10, 20, 30];
for x in &arr { println!("{x}"); }

// Lines from a string
let text = "a\nb\nc";
for line in text.lines() { println!("{line}"); }

Key Takeaways