13.3 Creating Custom Iterators
Creating custom iterators allows you to tailor iteration to specific needs.
13.3.1 Defining a Custom Iterator Struct
Let's create a custom range iterator named MyRange
.
#![allow(unused)] fn main() { struct MyRange { current: u32, end: u32, } impl MyRange { fn new(start: u32, end: u32) -> Self { MyRange { current: start, end } } } }
13.3.2 Implementing the Iterator
Trait
Implement the Iterator
trait by defining the next()
method.
#![allow(unused)] fn main() { impl Iterator for MyRange { type Item = u32; fn next(&mut self) -> Option<Self::Item> { if self.current < self.end { let result = self.current; self.current += 1; Some(result) } else { None } } } }
13.3.3 Using Custom Iterators in for
Loops
struct MyRange { current: u32, end: u32, } impl MyRange { fn new(start: u32, end: u32) -> Self { MyRange { current: start, end } } } impl Iterator for MyRange { type Item = u32; fn next(&mut self) -> Option<Self::Item> { if self.current < self.end { let result = self.current; self.current += 1; Some(result) } else { None } } } fn main() { let range = MyRange::new(10, 15); for number in range { print!("{} ", number); } // Output: 10 11 12 13 14 }
13.3.4 Building Complex Iterators
Example: Fibonacci Sequence Iterator
#![allow(unused)] fn main() { struct Fibonacci { current: u32, next: u32, max: u32, } impl Fibonacci { fn new(max: u32) -> Self { Fibonacci { current: 0, next: 1, max } } } impl Iterator for Fibonacci { type Item = u32; fn next(&mut self) -> Option<Self::Item> { if self.current > self.max { None } else { let new_next = self.current + self.next; let result = self.current; self.current = self.next; self.next = new_next; Some(result) } } } }
Using the Fibonacci Iterator:
struct Fibonacci { current: u32, next: u32, max: u32, } impl Fibonacci { fn new(max: u32) -> Self { Fibonacci { current: 0, next: 1, max } } } impl Iterator for Fibonacci { type Item = u32; fn next(&mut self) -> Option<Self::Item> { if self.current > self.max { None } else { let new_next = self.current + self.next; let result = self.current; self.current = self.next; self.next = new_next; Some(result) } } } fn main() { let fib = Fibonacci::new(21); for number in fib { print!("{} ", number); } // Output: 0 1 1 2 3 5 8 13 21 }