如何在 Rust 中包含 dyn Iterator 的结构体上实现 Clone? [重复]

问题描述 投票:0回答:2

我在 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]
)并以当前计数器值作为参数调用一些闭包

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9fb31441d9007d51c050bdd9e8f2d5c7

rust iterator clone
2个回答
1
投票

因为

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
为条件,这是不必要的。


0
投票

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() {

}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.