0Pricing
Learn Rust Coding · Lesson

The Iterator Trait

next and laziness.

The Iterator Trait is a free Learn Rust Coding lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is an Iterator?

An iterator is anything that produces a sequence of values, one at a time. In Rust, iterators are the idiomatic way to process collections like vectors, ranges, and slices.

The whole concept is built on a single trait: Iterator. Once a type implements it, you get dozens of useful methods for free.

The Iterator Trait

The Iterator trait has one required method, next, and one associated type, Item:

  • type Item — the kind of value produced
  • fn next(&mut self) -> Option<Self::Item> — returns the next value

It returns Some(value) while values remain, then None when finished.

fn main() {
    let v = vec![10, 20, 30];
    let mut it = v.iter();
    println!("{:?}", it.next());
    println!("{:?}", it.next());
    println!("{:?}", it.next());
    println!("{:?}", it.next());
}

next Returns Option

Each call to next advances the iterator and hands you an Option. Some wraps a real value; None signals the end.

Notice that next takes &mut self — calling it changes internal state so the next call returns a different value.

fn main() {
    let mut it = (1..4).into_iter();
    while let Some(n) = it.next() {
        println!("got {}", n);
    }
    println!("done");
}

Iterators Are Lazy

Creating an iterator does nothing on its own. No values are computed until something asks for them. This is called laziness.

In the next example the map closure never runs, because we never consume the iterator.

fn main() {
    let nums = vec![1, 2, 3];
    let _doubled = nums.iter().map(|x| {
        println!("mapping {}", x);
        x * 2
    });
    println!("nothing printed above this line");
}

Consuming Triggers Work

To make a lazy iterator actually run, you consume it. A for loop is the simplest consumer: it calls next repeatedly until None.

Now the same map closure runs for every element.

fn main() {
    let nums = vec![1, 2, 3];
    for x in nums.iter().map(|x| x * 2) {
        println!("value {}", x);
    }
}

Three Ways to Iterate

Collections offer three iterator-producing methods:

  • iter() — yields &T (borrows)
  • iter_mut() — yields &mut T (mutable borrows)
  • into_iter() — yields T (takes ownership)
fn main() {
    let mut v = vec![1, 2, 3];
    for x in v.iter_mut() {
        *x += 10;
    }
    println!("{:?}", v);
}

for Loops Use into_iter

When you write for x in collection directly, Rust calls into_iter(), which consumes the collection.

After this loop you cannot use v again because it was moved into the iterator.

fn main() {
    let v = vec![String::from("a"), String::from("b")];
    for s in v {
        println!("{}", s);
    }
    // v is no longer usable here
}

Ranges Are Iterators

A range like 0..5 is itself an iterator producing 0, 1, 2, 3, 4. The end is exclusive. Use 0..=5 for an inclusive range.

Ranges are great for counting loops without manual index tracking.

fn main() {
    for i in 0..5 {
        print!("{} ", i);
    }
    println!();
    for i in 1..=3 {
        print!("{} ", i);
    }
    println!();
}

count: A Simple Consumer

count consumes the whole iterator and returns how many items it produced. It is one of many consuming adapters.

Because it consumes, you cannot reuse the iterator afterward.

fn main() {
    let total = (1..=100).count();
    println!("there are {} numbers", total);
}

sum: Folding Into One Value

sum adds every item together and returns a single value. You often annotate the target type so Rust knows what to produce.

This is more concise and clearer than a manual accumulator loop.

fn main() {
    let total: i32 = (1..=5).sum();
    println!("sum is {}", total);
}

Why Iterators Matter

Iterators give you composability: chain small operations into clear pipelines. They are also zero-cost — the compiler optimizes them to be as fast as hand-written loops.

Mastering next, laziness, and consumption is the foundation for everything that follows.

Quick Check

Test your understanding of the Iterator trait.

Recap

You learned the core of Rust iterators:

  • The Iterator trait needs only next and an Item type
  • next returns Some(value) then None
  • Iterators are lazy — they do nothing until consumed
  • iter, iter_mut, and into_iter control borrowing vs ownership
  • Consumers like for, count, and sum drive the work

Frequently asked questions

Is the “The Iterator Trait” lesson free?

Yes — the full text of “The Iterator Trait” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “The Iterator Trait”?

next and laziness. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “The Iterator Trait” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The Iterator Trait
  2. map, filter, collect
  3. Adapters and Consumers
  4. Custom Iterators
← Back to Learn Rust Coding