从表达式返回盒装克隆迭代器的正确方法是什么?例如:
fn example() -> Box<Iterator<Item = String> + Clone> {
unimplemented!()
}
这给我一个错误,只能以这种方式指定自动特征:
error[E0225]: only auto traits can be used as additional traits in a trait object
--> src/main.rs:1:47
|
1 | fn example() -> Box<Iterator<Item = String> + Clone> {
| ^^^^^ non-auto additional trait
这是我的真实代码:
let my_iterator = {
if a {
Box::new(/* ... */) as Box<Iterator<Item = String> + Clone>
} else {
Box::new(/* ... */) as Box<Iterator<Item = String> + Clone>
}
};
let pb = ProgressBar::new(my_iterator.clone().count() as u64);
如果考虑其他建议:两个分支代表一个从文件加载的路径,另一个路径用于自动生成,如果不需要,我宁愿不将内容保存在内存中。
答案 0 :(得分:2)
Iterator
是 trait ,因此Box<Iterator>
是特质对象。
Clone
无法成为特质对象,因为它需要了解Self
,因此我们按照How to clone a struct storing a boxed trait object?中的说明操作:
trait CloneIterator: Iterator {
fn clone_box(&self) -> Box<CloneIterator<Item = Self::Item>>;
}
impl<T> CloneIterator for T
where
T: 'static + Iterator + Clone,
{
fn clone_box(&self) -> Box<CloneIterator<Item = Self::Item>> {
Box::new(self.clone())
}
}
fn example(switch: bool) -> Box<CloneIterator<Item = String>> {
let i = vec!["a".into(), "b".into()].into_iter();
if switch {
Box::new(i)
} else {
Box::new(i.take(1))
}
}
fn main() {
let i = example(true);
let i2 = i.clone_box();
let j = example(false);
let j2 = j.clone_box();
}
另见: