我可以编写一个与此C代码等效的Rust for
循环:
for(int i = 2; i <= 128; i=i*i){
//do something
}
我只看到像
这样的事情for i in 0..128 { /* do something */ }
或
let v = vec![0, 1, 2, /* ... */ ];
for i in v.iter() { /* do something */ }
我应该使用while
循环吗?
答案 0 :(得分:7)
您可以始终创建一个自定义迭代器,它可以执行您需要的任何独特序列:
struct Doubling {
current: u64,
max: u64,
}
impl Iterator for Doubling {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.current > self.max {
None
} else {
let v = Some(self.current);
self.current *= 2;
v
}
}
}
fn main() {
let iter = Doubling { current: 2, max: 128 };
let values: Vec<_> = iter.collect();
println!("{:?}", values);
}
重要的是要认识到这个逻辑(就像原始的C!)在值加倍超出类型大小时会出现令人讨厌的边缘情况。
在这个特定的情况下,你还可以认识到你有一个指数级数:
fn main() {
let iter = (1..8).map(|p| 2i32.pow(p));
let values: Vec<_> = iter.collect();
println!("{:?}", values);
}
如果您想真正进行实验,请查看Lazy sequence generation in Rust。改编自:
#![feature(generators, generator_trait, conservative_impl_trait)]
use std::ops::{Generator, GeneratorState};
fn doubling(mut start: u64, max: u64) -> impl Iterator<Item = u64> {
GeneratorIteratorAdapter(move || {
while start <= max {
yield start;
start *= 2;
}
})
}
fn main() {
let iter = doubling(2, 128);
let sum: Vec<_> = iter.collect();
println!("{:?}", sum);
}
/* copy-pasta */
struct GeneratorIteratorAdapter<G>(G);
impl<G> Iterator for GeneratorIteratorAdapter<G>
where
G: Generator<Return = ()>,
{
type Item = G::Yield;
fn next(&mut self) -> Option<Self::Item> {
match self.0.resume() {
GeneratorState::Yielded(x) => Some(x),
GeneratorState::Complete(_) => None,
}
}
}
答案 1 :(得分:5)
我可以编写一个等效于此C代码的for循环:
具体而言,是的:
extern crate itertools;
for i in itertools::iterate(2, |&i| i*i).take_while(|&i| i <= 128) {
// do something
}
但总的来说,没有。没有单一的直接等同于C&#39 {s} for
循环的所有可能用途。如果没有办法使用迭代器编写它,那么是的,你需要使用更通用的循环形式:
{
let mut i = 2;
while i <= 128 {
// do something
i = i*i;
}
}