Bana öyle geliyor ki, .step_by
yöntem kararlı hale gelene kadar , bir kişi istediğiniz şeyi kolayca başarabilir Iterator
( Range
zaten gerçekte olan budur ):
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);
}
}
Birinin farklı türde birden çok aralığı yinelemesi gerekiyorsa, kod aşağıdaki gibi genel yapılabilir:
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);
}
}
Sonsuz bir döngü gerekliyse, açık uçlu bir yapı oluşturmak için üst sınır kontrolünü ortadan kaldırmayı size bırakacağım ...
Bu yaklaşımın avantajları, for
şekerleme ile çalışan ve dengesiz özellikler kullanılabilir hale geldiğinde bile çalışmaya devam edecek olmasıdır; ayrıca, standart ' Range
leri kullanan şekersiz yaklaşımın aksine, birden fazla .next()
çağrı ile verimliliği kaybetmez . Dezavantajları, yineleyiciyi kurmak için birkaç satır kod gerektirmesidir, bu nedenle yalnızca çok sayıda döngüye sahip kod için buna değebilir.