编辑说明:此代码示例来自Rust 1.0之前的版本,不是符合语法的Rust 1.0代码。更新后的代码版本会产生不同的错误,但答案仍包含有价值的信息。
我想创建一个生成质数流的迭代器。我的一般思路是将一个迭代器与连续的过滤器包装起来,例如,您可以从以下内容开始:
let mut n = (2..N)
然后针对每个质数,您会改变迭代器并增加一个过滤器。
let p1 = n.next()
n = n.filter(|&x| x%p1 !=0)
let p2 = n.next()
n = n.filter(|&x| x%p2 !=0)
我试图使用以下代码,但似乎无法使其工作。
struct Primes {
base: Iterator<Item = u64>,
}
impl<'a> Iterator for Primes<'a> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
let p = self.base.next();
match p {
Some(n) => {
let prime = n.clone();
let step = self.base.filter(move |&: &x| {x%prime!=0});
self.base = &step as &Iterator<Item = u64>;
Some(n)
},
_ => None
}
}
}
我曾尝试过各种变化,但似乎无法使生命周期和类型匹配。目前编译器告诉我:
- 我不能改变self.base
- 变量prime的寿命不够长
solution.rs:16:17: 16:26 error: cannot borrow immutable borrowed content `*self.base` as mutable
solution.rs:16 let p = self.base.next();
^~~~~~~~~
solution.rs:20:28: 20:37 error: cannot borrow immutable borrowed content `*self.base` as mutable
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
^~~~~~~~~
solution.rs:21:30: 21:34 error: `step` does not live long enough
solution.rs:21 self.base = &step as &Iterator<Item = u64>;
^~~~
solution.rs:15:39: 26:6 note: reference must be valid for the lifetime 'a as defined on the block at 15:38...
solution.rs:15 fn next(&mut self) -> Option<u64> {
solution.rs:16 let p = self.base.next();
solution.rs:17 match p {
solution.rs:18 Some(n) => {
solution.rs:19 let prime = n.clone();
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
...
solution.rs:20:71: 23:14 note: ...but borrowed value is only valid for the block suffix following statement 1 at 20:70
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
solution.rs:21 self.base = &step as &Iterator<Item = u64>;
solution.rs:22 Some(n)
solution.rs:23 },
error: aborting due to 3 previous errors
为什么Rust不允许我这样做?
base
的实际大小随着越来越多的嵌套而变化。因此,我们需要使用堆分配,以使Primes
的大小始终保持恒定。 - Shepmaster