--- date: 2020-09-23 id: a01bfc26-dece-4741-829b-d164ba9522bb title: Rust Iterators --- # Syntax ``` rust fn main() { let v1 = vec![1, 2, 3]; let v1_iter = v1.iter(); for val in v1_iter { println!("Got: {}", val); } } ``` # Iterator Trait All iterators implement a [trait](20200917163203-traits) named [Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) ``` rust #![allow(unused)] fn main() { pub trait Iterator { type Item; fn next(&mut self) -> Option; // methods with default implementations elided } } ``` # Iterator methods ## next ``` rust #[cfg(test)] mod tests { #[test] fn iterator_demonstration() { let v1 = vec![1, 2, 3]; let mut v1_iter = v1.iter(); assert_eq!(v1_iter.next(), Some(&1)); assert_eq!(v1_iter.next(), Some(&2)); assert_eq!(v1_iter.next(), Some(&3)); assert_eq!(v1_iter.next(), None); } } fn main() {} ``` ## sum ``` rust #[cfg(test)] mod tests { #[test] fn iterator_sum() { let v1 = vec![1, 2, 3]; let v1_iter = v1.iter(); let total: i32 = v1_iter.sum(); assert_eq!(total, 6); } } fn main() {} ``` # Methods that produce other Iterators By their nature iterators are lazy so the following won't work: ``` rust fn main() { let v1: Vec = vec![1, 2, 3]; v1.iter().map(|x| x + 1); } ``` The Iterator must be consumed, using the [collect](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect) method: ``` rust fn main() { let v1: Vec = vec![1, 2, 3]; let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); assert_eq!(v2, vec![2, 3, 4]); } ``` # Creating your own Iterators ``` rust struct Counter { count: u32, } impl Counter { fn new() -> Counter { Counter { count: 0 } } } impl Iterator for Counter { type Item = u32; fn next(&mut self) -> Option { if self.count < 5 { self.count += 1; Some(self.count) } else { None } } } fn main() { let counter = Counter::new(); for val in counter { println!("Got: {}", val); } } ```