如何使用1以外的步骤迭代Rust中的范围?我来自C++背景,所以我想做点什么
for(auto i = 0; i <= n; i+=2) {
//...
}
Run Code Online (Sandbox Code Playgroud)
在Rust中我需要使用该range函数,并且似乎没有第三个参数可用于自定义步骤.我怎么能做到这一点?
Pil*_*ill 72
range_step_inclusive并且range_step早已不复存在.
从Rust 1.28开始,Iterator::step_by是稳定的:
fn main() {
for x in (1..10).step_by(2) {
println!("{}", x);
}
}
Run Code Online (Sandbox Code Playgroud)
Gor*_*ood 10
在我看来,在.step_by方法稳定之前,人们可以轻松地完成你想要的东西Iterator(Range无论如何真正是这样):
struct SimpleStepRange(isize, isize, isize); // start, end, and step
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要迭代不同类型的多个范围,则可以使代码通用如下:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要无限循环,我会留给你消除上界检查以创建一个开放式结构...
这种方法的优点是可以for加糖,并且即使在不稳定的特征变得可用时也会继续工作; 此外,与使用标准Ranges 的去糖方法不同,它不会因多次.next()调用而失去效率.缺点是需要几行代码才能设置迭代器,因此对于具有大量循环的代码来说可能是值得的.
您将编写 C++ 代码:
for (auto i = 0; i <= n; i += 2) {
//...
}
Run Code Online (Sandbox Code Playgroud)
...在 Rust 中就像这样:
let mut i = 0;
while i <= n {
// ...
i += 2;
}
Run Code Online (Sandbox Code Playgroud)
我认为 Rust 版本也更具可读性。
如果您要单步执行预定义的值,并且像 2 这样小,您可能希望使用迭代器手动单步执行。例如:
let mut iter = 1..10;
loop {
match iter.next() {
Some(x) => {
println!("{}", x);
},
None => break,
}
iter.next();
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用它来步进任意数量(尽管这肯定会变得越来越长且难以消化):
let mut iter = 1..10;
let step = 4;
loop {
match iter.next() {
Some(x) => {
println!("{}", x);
},
None => break,
}
for _ in 0..step-1 {
iter.next();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23006 次 |
| 最近记录: |