Iterators

Iterators in Rust provide a way to lazily evaluate a sequence of values. All iterators implement the trait, which has one associated type,, and one method, , with the following signature:

Calling  progresses the iterator and returns   with the next value. This is often called consuming the next value. When the iterator is finished, calling  returns.

Iterators are analogous to the  monad in Haskell, and iterators in many other languages like Python.

and loops
is a trait that converts any collection into an iterator over its elements. It is implemented for all collection and collection-like types in the standard library, such as, , and slices. It is also implemented for all iterators as the identity function.

It is most useful in for loops, which can iterate over any type that implements. It first converts the variable into an iterator and then repeatedly calls its  method until it returns   -   is therefore logically equivalent to , but looks cleaner and clearer.

and
The is the opposite of   - it converts an iterator into a collection instead of the other way around. It is primarily not used directly, but rather through the iterator's method.

is implemented for all collection types, such as,  ,   etc, but is also implemented for   and  , where it takes an iterator of  s and  s and 'flattens' it into a single   or.

Example
It can also be used to convert one collection type into another: Flattening s:

In some situations, Rust can produce more efficient code if it knows the number of elements of the iterator up front. For example, when collecting into a, Rust can set the correct capacity to start with and avoid reallocation. The  trait provides this, and so iterators that implement this can be collected very efficiently.

Unless you are manually implementing an iterator, you don't generally have to worry about whether  is implemented or not — standard library iterators implement it wherever it is possible.

Fused iterators
Calling  on an iterator that has already returned   once has unspecified (but not undefined) behavior. It might return,  , or even panic. However, it can be useful to have an iterator that will continue to return  after finishing. The trait guarantees this, and it is implemented by all iterators that have this behavior. Additionally, any iterator can become fused by calling on it, which for already-fused iterators is a no-op and for unfused iterators will keep track of whether the iterator has ended or not.

Double-ended iterators
Sometimes it's necessary to iterate over something in reverse direction. Iterators that implement the trait require a   method which consumes an element from the end of the iterator. Double ended iterators also provide a  method, which reverses the iterator. This means that calling  now consumes an element from the end of the iterator, and   consumes an element from the start.

Adapters
By itself, looping through all elements of an iterator in order is a fairly basic operation. The true power of iterators comes from adapters — additional methods on the  trait, which perform various transformations on the iterator. Since those are defined and implemented by default on the  trait itself, they are automatically usable with any iterator.

Some adapters take an iterator and return one final value from it. Those are commonly referred to as consuming adapters, since the consume the iterator and all of the elements it produces. The opposite behavior is known as non-consuming adapters — those take an iterator and create a new one based on the one which has been provided. Iterating through the new iterator will then perform various transformations on the values.