0Pricing
Learn Rust Coding · Lesson

Custom Iterators

Implement Iterator.

Custom Iterators is a free Learn Rust Coding lesson on CoddyKit — lesson 4 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.

Make Your Own Iterator

You are not limited to built-in iterators. By implementing the Iterator trait on your own type, it gains every adapter and consumer for free.

All you must provide is the Item type and a next method.

A Counter Struct

Start with a struct that holds the iterator's state. A simple counter just needs a current value.

struct Counter {
    count: u32,
}

fn main() {
    let c = Counter { count: 0 };
    println!("start at {}", c.count);
}

Implementing next

Implement Iterator for the struct. Set type Item, then write next to advance the state and return Some until a stopping condition, then None.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

fn main() {
    let mut c = Counter { count: 0 };
    println!("{:?}", c.next());
    println!("{:?}", c.next());
}

Using It in a for Loop

Once next exists, your type works in a for loop just like any standard iterator.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    for n in (Counter { count: 0 }) {
        print!("{} ", n);
    }
    println!();
}

Free Adapters and Consumers

Because you implemented one method, the entire iterator toolbox now applies. Here we sum the squares of paired counter values.

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let total: u32 = Counter { count: 0 }.map(|x| x * 2).sum();
    println!("{}", total);
}

A Constructor Method

Add a new function so users do not poke at internal fields. This is cleaner and lets you keep the field private.

struct Counter { count: u32 }

impl Counter {
    fn new() -> Counter { Counter { count: 0 } }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 3 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let v: Vec<u32> = Counter::new().collect();
    println!("{:?}", v);
}

A Fibonacci Iterator

Iterators can carry richer state. A Fibonacci generator keeps the last two values and updates them on each next call.

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let current = self.a;
        self.a = self.b;
        self.b = current + self.b;
        Some(current)
    }
}

fn main() {
    let fib = Fib { a: 0, b: 1 };
    let seq: Vec<u64> = fib.take(8).collect();
    println!("{:?}", seq);
}

Infinite Iterators Are Fine

The Fibonacci iterator never returns None — it is infinite. That is safe because laziness means values are produced only on demand. Use take to bound it.

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let c = self.a;
        self.a = self.b;
        self.b = c + self.b;
        Some(c)
    }
}

fn main() {
    let big = Fib { a: 0, b: 1 }.nth(20);
    println!("{:?}", big);
}

Iterating Over a Wrapper Type

Often you implement Iterator on a helper struct that borrows your data. Here a stepper yields every second number from a range stored inside.

struct EvenUpTo { current: u32, max: u32 }

impl Iterator for EvenUpTo {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.current > self.max { return None; }
        let value = self.current;
        self.current += 2;
        Some(value)
    }
}

fn main() {
    let evens: Vec<u32> = (EvenUpTo { current: 0, max: 10 }).collect();
    println!("{:?}", evens);
}

Why Build Custom Iterators?

Custom iterators let you stream values without allocating a full collection, model infinite or computed sequences, and give callers a familiar, composable interface.

One small next method unlocks the whole ecosystem.

Design Tips

Keep your state minimal, return None exactly once at the end (or never for infinite ones), and avoid heavy work inside next so laziness stays cheap.

Quick Check

Implementing the Iterator trait.

Recap

You built custom iterators:

  • Hold state in a struct, then impl Iterator
  • Define type Item and write next
  • You instantly get adapters and consumers for free
  • Iterators can be finite or infinite; use take to bound infinite ones

Frequently asked questions

Is the “Custom Iterators” lesson free?

Yes — the full text of “Custom Iterators” 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 “Custom Iterators”?

Implement Iterator. 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 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Custom Iterators” 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