我在 Rust 中有以下结构:
#[derive(Clone)]
pub struct EquationIterator<F> {
counter: Box<dyn Iterator<Item = usize>>,
formula: Arc<dyn Fn(usize) -> Equation<F>>,
}
我必须使用
Arc
来包装闭包,否则我无法在结构上实现 Clone
。即使这样,我仍然无法导出 Clone
,因为编译器抱怨 dyn Iterator
没有实现 Clone
。
我尝试过手动实现
Clone
,但也没有成功。有什么想法吗?
为了添加更多颜色,该结构是一个迭代器,它遍历某个任意范围(例如
counter = [2, 5, 9]
)并以当前计数器值作为参数调用一些闭包
因为
Clone
不是 对象安全(它将返回实际类型,而不是 Box<dyn Clone>
),所以您需要一个解决方法。你几乎可以使用这个问题中的方法,除非因为你不拥有Iterator
特征,所以你需要创建一个新特征。 (游乐场)
trait ClonableIterator: Iterator {
fn clone_box(&self) -> Box<dyn ClonableIterator<Item = Self::Item>>;
}
impl<T, I> ClonableIterator for T
where
T: Iterator<Item = I> + Clone + 'static,
{
fn clone_box(&self) -> Box<dyn ClonableIterator<Item = I>> {
Box::new(self.clone())
}
}
然后你可以在你的结构中存储这个特征的特征对象。
counter: Box<dyn ClonableIterator<Item = usize>>
您可以使用
Clone
为您的结构实现 clone_box
。
impl<F> Clone for EquationIterator<F> {
fn clone(&self) -> Self {
EquationIterator {
counter: self.counter.clone_box(),
formula: self.formula.clone(),
}
}
}
您也可以对
Fn
特征执行此操作,我已将其升级为 FnMut
,因为它现在是独占的。
trait ClonableFnMut<T, O>: FnMut(T) -> O {
fn clone_box(&self) -> Box<dyn ClonableFnMut<T, O>>;
}
impl<F, T, O> ClonableFnMut<T, O> for F
where
F: FnMut(T) -> O + Clone + 'static,
{
fn clone_box(&self) -> Box<dyn ClonableFnMut<T, O>> {
Box::new(self.clone())
}
}
然后您可以将其添加到结构中。
formula: Box<dyn ClonableFnMut<usize, F>>
并更改您的
Clone
实现。
formula: self.formula.clone_box()
我无法完全让它与 dyn-clone 一起使用,但可能有办法。
请注意,无论如何,您都需要手动实现
Clone
,因为派生会使其以 F
为 Clone
为条件,这是不必要的。
Iterator
的实现者可能不可克隆。您需要向编译器指定仅允许实现 Clone
和 Interator
的类型。
use std::sync::Arc;
#[derive(Clone)]
pub struct EquationIterator<F, I: Iterator<Item = usize> + Clone> {
counter: Box<I>,
formula: Arc<dyn Fn(usize) -> F>,
}
fn main() {
}