আমার কাছে মনে হয় যে .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গুলি ব্যবহার করে ডি-সুগারযুক্ত পদ্ধতির বিপরীতে , এটি একাধিক .next()কল করে দক্ষতা হারাবে না । অসুবিধাগুলি হ'ল এটিরেটর সেট আপ করতে কোডের কয়েক লাইন লাগে তাই কেবলমাত্র কোডের জন্য এটি উপযুক্ত হতে পারে যাতে প্রচুর লুপ থাকে।