liveBook · Manning

Iterator

As explained in Idiomatic Rust

An iterator is an abstraction that produces a sequence of values one element at a time according to a traversal protocol.

An iterator provides a way to visit values one at a time without making each caller manage traversal. In Rust, the Iterator trait makes that convention reusable: implement its small core, then use methods such as map(), filter(), fold(), and last(). Iterators also pair naturally with closures to express operations on data structures. section 3.2.3 section 3.3

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

The essential implementation supplies an associated Item type and next(&mut self) -> Option<Self::Item>. Each call asks for the next item; None represents the end. section 3.2.3

Traversing a linked list

A linked list can store its current traversal position and implement next() to return the head first, then follow each node’s next pointer. Its Item is a pointer to a list node. With Iterator implemented, last() finds the final node; the example then uses that node to append another item. section 3.2.3

impl<T> Iterator for LinkedList<T> {
    type Item = ListItemPtr<T>;          #1
    fn next(&mut self) -> Option<Self::Item> {
        match &self.cur_iter.clone() {     #2
            None => {
                self.cur_iter = Some(self.head.clone());     #3
            }
            Some(ptr) => {
                self.cur_iter = ptr.borrow().next.clone();     #4
            }
        }
        self.cur_iter.clone()     #5
    }
}

The implementation shows the traversal state, the associated Item type, and next() advancing through linked nodes. section 3.2.3

Ownership matters when choosing an iterator. Typically, iter() yields references to items, while into_iter() moves items out of the underlying sequence. For a library interface, accepting an iterator can also allow more kinds of input than requiring a Vec; a slice is another, somewhat less flexible option. Choose the interface your callers need rather than introducing a custom collection by default. section 3.3 section 6.4

How Idiomatic Rust covers it

How deep it goes
Works from the Iterator trait’s required Item and next() to a linked-list implementation and append example.
Examples
Demonstrates a linked-list iterator whose last() method locates the node used for append().
What it assumes
Assumes familiarity with generics, traits, and pattern matching, while briefly explaining Rc and RefCell for the linked-list example.
What you can do after
Build it from scratch by implementing Iterator for a linked list and using its provided methods.
How it connects
Connects iterators with closures, traits, linked lists, borrowing, ownership, and library interface design.

Also explained in

Compare how 15 books explain iterator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Idiomatic Rust. The section links point to the parts of the book it draws on.