Implementing Custom Iterators in Rust
Iterators are a fundamental concept in Rust, enabling efficient and expressive data processing. This challenge asks you to implement a custom iterator that generates a sequence of numbers based on a given starting value, a step, and a limit. Successfully completing this exercise will deepen your understanding of Rust's iterator protocol and trait system.
Problem Description
You are tasked with creating a struct named NumberGenerator that implements the Iterator trait. This struct should take three parameters in its constructor:
start: Ani32representing the starting number of the sequence.step: Ani32representing the increment between numbers in the sequence.limit: Ani32representing the upper bound (exclusive) of the sequence. The iterator should stop generating numbers when the next number in the sequence would exceed this limit.
The NumberGenerator struct should implement the Iterator trait, providing a next() method. The next() method should return an Option<i32>.
- If there are more numbers to generate within the limit, it should return
Some(next_number), wherenext_numberis the next number in the sequence. - If the limit has been reached and no more numbers can be generated, it should return
None.
The sequence should be generated by adding the step to the previous number.
Examples
Example 1:
Input: NumberGenerator { start: 1, step: 2, limit: 10 }
Output: Some(1), Some(3), Some(5), Some(7), Some(9), None
Explanation: The sequence starts at 1, increments by 2, and stops when the number exceeds 10.
Example 2:
Input: NumberGenerator { start: 5, step: -1, limit: 0 }
Output: Some(5), Some(4), Some(3), Some(2), Some(1), None
Explanation: The sequence starts at 5, decrements by 1, and stops when the number is less than or equal to 0.
Example 3:
Input: NumberGenerator { start: 10, step: 0, limit: 20 }
Output: Some(10), None
Explanation: If the step is 0, the iterator should only return the starting value once.
Constraints
start,step, andlimitwill bei32integers.- The
limitwill always be greater than or equal tostart. - The
stepcan be positive, negative, or zero. - The iterator should be efficient and avoid unnecessary computations.
- The code should adhere to Rust's ownership and borrowing rules.
Notes
- Remember to implement the
Iteratortrait, which requires thenext()method. - Consider how to handle the case where the
stepis zero. - Think about how to ensure the iterator stops correctly when the limit is reached, regardless of the
stepvalue. - The
next()method should update the internal state of theNumberGeneratorto track the next number in the sequence. - Use
Option<i32>to indicate whether there are more elements to iterate over.