我试图用可克隆的迭代器对象定义一个结构。到目前为止,我已达到:
pub struct UseClonableIterator2<'a,T:'a> {
it: &'a (Iterator<Item=T> + Clone)
}
由于Clone
不是&#34;内置特征&#34;所以无法编译:
x.rs:2:33: 2:38 error: only the builtin traits can be used as closure or object bounds [E0225]
x.rs:2 it: &'a (Iterator<Item=T> + Clone)
^~~~~
x.rs:2:33: 2:38 help: run `rustc --explain E0225` to see a detailed explanation
一个选项可能是为迭代器添加另一个类型参数,但这会使定义复杂化,我宁愿避免使用它。
答案 0 :(得分:3)
您需要动态调度吗?如果没有,您应该使用通用参数而不是特征对象 - 它不一定会使定义复杂化。试试这个例子:
pub struct UseClonableIterator<I: Iterator + Clone> {
it: I
}
在此处保存在您的类型中实现Iterator
和Clone
的对象。如果你只是想引用它,这当然也是可能的:
pub struct UseClonableIterator2<'a, I: Iterator + Clone + 'a> {
it: &'a I
}
请注意,在两个示例中,我们都使用静态分派和单态化。这通常会带来更好的性能。
但是,这并不总是可行的 - 有时需要使用特征对象进行动态调度(就像你试图实现它一样)。在这种情况下,您只能通过重构代码来解决您的问题,因为Rust还不允许具有多个特征的特征对象。
答案 1 :(得分:0)
如果需要动态调度迭代器,意味着Iterator
实现类型不能是UseClonableIterator
的类型参数,那么我将使用我的objekt
包来解决此问题。
#[macro_use]
extern crate objekt;
trait ClonableIterator: Iterator + objekt::Clone {}
impl<I> ClonableIterator for I where I: Iterator + objekt::Clone {}
clone_trait_object!(<T> ClonableIterator<Item = T>);
#[derive(Clone)]
struct UseClonableIterator<T> {
it: Box<ClonableIterator<Item = T>>,
}
fn main() {
let thing1 = UseClonableIterator {
it: Box::new(vec![1, 2, 3].into_iter()),
};
let thing2 = thing1.clone();
// prints 1 2 3 from thing1's iterator
for i in thing1.it {
println!("{}", i);
}
// prints 1 2 3 from thing2's iterator
for i in thing2.it {
println!("{}", i);
}
}