【发布时间】:2022-01-08 03:40:27
【问题描述】:
我正在尝试实现类似于以下 Haskell 代码的 Rust 迭代器:
primes :: [Integer]
primes = nextPrime [2..]
where
nextPrime (x:xs) = x : nextPrime (filter (notDivBy x) xs)
notDivBy a x = a `mod` x /= 0
到目前为止我的尝试 (playground):
// as pointed out in a comment this can simply return Primes and not use Box::new
fn primes() -> Box<dyn Iterator<Item = usize>> {
Box::new(Primes::new())
}
struct Primes {
nums: Box<dyn Iterator<Item = usize>>,
}
impl Primes {
fn new() -> Self {
Primes { nums : Box::new(2..) }
}
}
impl Iterator for Primes {
type Item = usize;
fn next(&mut self) -> Option<usize> {
let prime = self.nums.next().unwrap();
self.nums = Box::new(self.nums.filter(move |&n|!divides(prime, n)));
//use std::borrow::BorrowMut;
//*self.nums.borrow_mut() = self.nums.filter(move |&n|!divides(prime, n));
Some(prime)
}
}
pub fn divides(d: usize, n: usize) -> bool {
n % d == 0
}
不幸的是,这遇到了:
error[E0507]: cannot move out of `self.nums` which is behind a mutable reference
--> src/lib.rs:22:30
|
22 | self.nums = Box::new(self.nums.filter(move |&n| !divides(prime, n)));
| ^^^^^^^^^ move occurs because `self.nums` has type `Box<dyn Iterator<Item = usize>>`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
或者,如果您取消注释替代的 borrow_mut 代码:
error[E0277]: the trait bound `Box<(dyn Iterator<Item = usize> + 'static)>: BorrowMut<Filter<Box<dyn Iterator<Item = usize>>, [closure@src/lib.rs:24:52: 24:79]>>` is not satisfied
--> src/lib.rs:24:20
|
24 | *self.nums.borrow_mut() = self.nums.filter(move |&n|!divides(prime, n));
| ^^^^^^^^^^ the trait `BorrowMut<Filter<Box<dyn Iterator<Item = usize>>, [closure@src/lib.rs:24:52: 24:79]>>` is not implemented for `Box<(dyn Iterator<Item = usize> + 'static)>`
|
= help: the following implementations were found:
<Box<T, A> as BorrowMut<T>>
坦率地说,我什至不确定这两个中哪一个更接近工作。
【问题讨论】:
-
你对拳击的使用在这里很奇怪。为什么
primes()不只是返回Primes?为什么将(装箱!)迭代器存储到一个可以计数的东西而不是直接存储一个计数器?我认为如果你的目标是减少动态分配,它会简单得多。 -
@GManNickG,最初我没有这个拳击,但是建立过滤器链让编译器抱怨无法确定迭代器的大小,这促使我引入拳击。 IIRC。也许我对 Box 的使用有点过头了?
-
@GManNickG,我现在在代码中添加了一条评论。谢谢指点!
标签: haskell rust iterator primes