यह मुझे लगता है कि जब तक .step_by
विधि को स्थिर नहीं किया जाता है, तब तक कोई भी आसानी से पूरा कर सकता है जो आप चाहते हैं Iterator
(जो कि Range
वास्तव में वैसे भी हैं):
struct SimpleStepRange(isize, isize, isize);
impl Iterator for SimpleStepRange {
type Item = isize;
#[inline]
fn next(&mut self) -> Option<isize> {
if self.0 < self.1 {
let v = self.0;
self.0 = v + self.2;
Some(v)
} else {
None
}
}
}
fn main() {
for i in SimpleStepRange(0, 10, 2) {
println!("{}", i);
}
}
यदि किसी को विभिन्न प्रकारों की कई श्रेणियों को पुनरावृत्त करना है, तो कोड को निम्नानुसार सामान्य बनाया जा सकता है:
use std::ops::Add;
struct StepRange<T>(T, T, T)
where for<'a> &'a T: Add<&'a T, Output = T>,
T: PartialOrd,
T: Clone;
impl<T> Iterator for StepRange<T>
where for<'a> &'a T: Add<&'a T, Output = T>,
T: PartialOrd,
T: Clone
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
if self.0 < self.1 {
let v = self.0.clone();
self.0 = &v + &self.2;
Some(v)
} else {
None
}
}
}
fn main() {
for i in StepRange(0u64, 10u64, 2u64) {
println!("{}", i);
}
}
यदि अपरिमित लूप की आवश्यकता है, तो एक खुली हुई संरचना बनाने के लिए ऊपरी सीमा की जांच को समाप्त करने के लिए मैं इसे आपको छोड़ दूँगा ...
इस दृष्टिकोण का लाभ यह है कि चीनी के साथ काम करता है for
और अस्थिर सुविधाओं के उपयोग योग्य होने पर भी काम करना जारी रखेगा; इसके अलावा, मानक Range
s का उपयोग करते हुए डी-शर्करा वाले दृष्टिकोण के विपरीत , यह कई .next()
कॉलों द्वारा दक्षता नहीं खोता है । नुकसान यह है कि इटेरेटर सेट करने के लिए कोड की कुछ पंक्तियां लगती हैं इसलिए केवल कोड के लिए इसके लायक हो सकता है जिसमें बहुत सारे लूप हों।