Rust 标准库是否有一个函数,可以像 Java 8 Streams 提供的那样,在给定种子和 lambda 的情况下生成无限迭代器?如果不是,Rust 中的类似替代方案是什么?
Stream.iterate(1, x -> 2 * x);
Rust 标准库曾经在名为 unfold
下具有类似的功能,但它从未稳定过,最终被删除。它现在位于迭代工具箱中:
extern crate itertools;
use itertools::Unfold;
fn main() {
let x = Unfold::new(1, |x| {
*x *= 2;
Some(*x)
});
for val in x.take(10) {
println!("{}", val);
}
}
请注意,它有点复杂,因为状态不必与迭代器返回的内容完全匹配,您可以控制迭代器何时停止。板条箱可能会接受顶部薄层的 PR,以提供您的确切实现。
1.7 开始,Rust 的标准库中没有任何内容可以等同于 Stream.iterate
(或者我找不到它!
我刚刚在 Rust 中启动了以下实现。它并不像Java实现那样简单,因为我们必须照顾所有权(因此需要Clone
和Option
与value
领域共舞)。
struct SequenceGenerator<T, F> {
value: Option<T>,
calc_next: F,
}
impl<T, F> SequenceGenerator<T, F>
where T: Clone,
F: FnMut(T) -> T
{
fn new(value: T, calc_next: F) -> SequenceGenerator<T, F> {
SequenceGenerator {
value: Some(value),
calc_next: calc_next,
}
}
}
impl<T, F> Iterator for SequenceGenerator<T, F>
where T: Clone,
F: FnMut(T) -> T
{
type Item = T;
fn next(&mut self) -> Option<T> {
let result = self.value.as_ref().unwrap().clone();
self.value = Some((self.calc_next)(self.value.take().unwrap()));
Some(result)
}
}
fn main() {
let seq_gen = SequenceGenerator::new(1, |x| 2 * x);
for i in seq_gen.take(10) {
println!("{}", i);
}
}
您可以使用标准scan
迭代器:
let seq_gen = iter::repeat(())
.scan(1, |r,_|{
let out = *r; *r = out * 2 ; Some(out)
});
或带有明确的闭包定义:
let seq_gen = iter::repeat(())
.scan((1, |x| x*2), |r,_|{
let out = r.0; r.0 = r.1(r.0); Some(out)
});
对于不可复制的类型,情况看起来更糟:
let seq_gen = iter::repeat(())
.scan(Some("Hello world".to_owned()), |r,_|{
let out = r.clone(); *r = r.take().map(|x| x+"!") ; out
});
对于这些类型,最好使用就地修改值的函数:
let seq_gen = iter::repeat(())
.scan("Hello world".to_owned(), |r,_|{
let out = r.clone(); r.push_str("!") ; Some(out)
});
我想知道是否
fn main() {
let x = (1..std::i32::MAX) .map(|x| x*2);
for i in x {
println!("{}", i);
}
}
对您来说将是一个令人满意的选择。