13.4 Advanced Iterator Concepts
13.4.1 Double-Ended Iterators
Double-Ended Iterators allow traversal from both the front and the back.
Example:
fn main() { let numbers = vec![1, 2, 3, 4, 5]; let mut iter = numbers.iter(); assert_eq!(iter.next(), Some(&1)); assert_eq!(iter.next_back(), Some(&5)); assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next_back(), Some(&4)); assert_eq!(iter.next(), Some(&3)); assert_eq!(iter.next_back(), None); }
Implementing DoubleEndedIterator
:
impl DoubleEndedIterator for MyRange {
fn next_back(&mut self) -> Option<Self::Item> {
if self.current < self.end {
self.end -= 1;
Some(self.end)
} else {
None
}
}
}
13.4.2 Fused Iterators
A Fused Iterator guarantees that after returning None
, it will always return None
.
Marking an Iterator as Fused:
#![allow(unused)] fn main() { use std::iter::FusedIterator; impl FusedIterator for MyRange {} }
13.4.3 Iterator Fusion
Iterator Fusion optimizes iterators by stopping computations after completion.
Example:
fn main() { let numbers = vec![1, 2, 3]; let mut iter = numbers.iter().filter(|&&x| x > 1); assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), Some(&3)); assert_eq!(iter.next(), None); assert_eq!(iter.next(), None); // No further computation }