我如何在Rust中使用1以外的步骤来遍历一个范围?我来自C++背景,所以我想做一些类似的事情
1
for(auto i = 0; i <= n; i+=2) { //... }
字符串在Rust中,我需要使用range函数,并且似乎没有第三个参数可以用于自定义步骤。我如何才能实现这一点?
range
esyap4oy1#
range_step_inclusive和range_step早就消失了。从Rust 1.28开始,Iterator::step_by是稳定的:
range_step_inclusive
range_step
Iterator::step_by
fn main() { for x in (1..10).step_by(2) { println!("{}", x); } }
字符串
muk1a3rh2#
在我看来,在.step_by方法稳定之前,人们可以很容易地用Iterator实现你想要的东西(这就是Range s的真正含义):
.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); } }
字符串如果需要对不同类型的多个范围进行编译,则可以将代码设置为泛型,如下所示:
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 sugaring一起工作,即使不稳定的特性变得可用,它也会继续工作;而且,与使用标准Range s的去糖方法不同,它不会因为多次.next()调用而降低效率。缺点是它需要几行代码来设置迭代器,所以可能只适合有很多循环的代码。
for
.next()
kiz8lqtg3#
你会写你的C++代码:
for (auto i = 0; i <= n; i += 2) { //... }
字符串在Rust中是这样的:
let mut i = 0; while i <= n { // ... i += 2; }
型我认为Rust版本也更可读。
7d7tgy0s4#
如果你要遍历一些预定义的东西,比如2,你可能希望使用迭代器手动遍历。例如:
let mut iter = 1..10; loop { match iter.next() { Some(x) => { println!("{}", x); }, None => break, } iter.next(); }
字符串你甚至可以用它来步进任意数量(尽管这肯定会变得越来越长,越来越难消化):
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(); } }
型
oalqel3c5#
将num机箱与range_step一起使用
5条答案
按热度按时间esyap4oy1#
range_step_inclusive
和range_step
早就消失了。从Rust 1.28开始,
Iterator::step_by
是稳定的:字符串
muk1a3rh2#
在我看来,在
.step_by
方法稳定之前,人们可以很容易地用Iterator
实现你想要的东西(这就是Range
s的真正含义):字符串
如果需要对不同类型的多个范围进行编译,则可以将代码设置为泛型,如下所示:
型
如果需要一个无限循环,我将把它留给你来消除上限检查,以创建一个开放式结构。
这种方法的优点是它可以与
for
sugaring一起工作,即使不稳定的特性变得可用,它也会继续工作;而且,与使用标准Range
s的去糖方法不同,它不会因为多次.next()
调用而降低效率。缺点是它需要几行代码来设置迭代器,所以可能只适合有很多循环的代码。kiz8lqtg3#
你会写你的C++代码:
字符串
在Rust中是这样的:
型
我认为Rust版本也更可读。
7d7tgy0s4#
如果你要遍历一些预定义的东西,比如2,你可能希望使用迭代器手动遍历。例如:
字符串
你甚至可以用它来步进任意数量(尽管这肯定会变得越来越长,越来越难消化):
型
oalqel3c5#
将num机箱与range_step一起使用