How `std::iter:: Map::next()` works?

Hi! I am confused about the working mechanism of std::iter::Map::next(), that is, Map in std::iter - Rust.

The source(Map in std::iter - Rust) indicates that self.iter.next() will be called, where self is of type std::iter::Map. As per source code, it seems like an infinite recursion, which doesn't make sense. Could anyone give some clues?

std::iter::Map is a so-called iterated adapter, meaning it stores another iterator and implements the Iterator trait using an adapted version of that iterator.

Map, specifically, is defined like this:

pub struct Map<I, F> {
    // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
    pub(crate) iter: I,
    f: F,
}

where iter is an iterator and f the function doing the mapping.

The .next() call is defined like this:

#[inline]
fn next(&mut self) -> Option<B> {
    self.iter.next().map(&mut self.f)
}

This calls the .next() method on the iterator stored in self.iter, and maps it via the Option::map method. It would recurse indefinitely if it said self.next() instead of self.iter.next(), but these iterators are distinct from each other and the former owns the latter.

5 Likes

Why? It doesn't call self.next(), it calls self.iter.next(). The field self.iter is a distinct value (and has a distinct type) from self.