Iterator
The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
The Iterator pattern is used to provide a standard way to traverse a collection of items without exposing the underlying implementation. It allows you to access the elements of a collection sequentially without needing to know the internal structure of the collection.
trait Iterator { fn has_next(&self) -> bool; fn next(&mut self) -> Option<&str>; } struct ConcreteIterator { index: usize, data: Vec<String>, } impl ConcreteIterator { fn new(data: Vec<String>) -> Self { Self { index: 0, data } } } impl Iterator for ConcreteIterator { fn has_next(&self) -> bool { self.index < self.data.len() } fn next(&mut self) -> Option<&str> { if self.has_next() { let item = &self.data[self.index]; self.index += 1; Some(item) } else { None } } } fn main() { let data = vec!["A".to_string(), "B".to_string(), "C".to_string()]; let mut iterator = ConcreteIterator::new(data); while iterator.has_next() { if let Some(item) = iterator.next() { println!("{}", item); } } }
struct Fibonnaci { current: u64, next: u64, } impl Iterator for Fibonnaci { type Item = u64; fn next (&mut self) -> Option<Self::Item> { let current = self.current; self.current = self.next; self.next = current + self.next; Some(current) } } fn fibonnaci() -> Fibonnaci { Fibonnaci { current: 0, next: 1 } } fn main() { let mut fib = fibonnaci(); for i in 0..=10 { if let Some(n) = fib.next() { println!("{} -> {}", i, n); } } }