如何迭代结构集合作为特征对象引用的迭代器?

时间:2017-11-07 10:48:43

标签: iterator rust polymorphism

我有一组struct对象。我想用特征对象的迭代器迭代集合,但是我不能为它创建一个合适的迭代器。我减少的测试代码是:

struct MyStruct {}
struct MyStorage(Vec<MyStruct>);

trait MyTrait {} // Dummy trait to demonstrate the problem
impl MyTrait for MyStruct {}

trait MyContainer {
    fn items<'a>(&'a self) -> Box<Iterator<Item = &'a MyTrait> + 'a>;
}
impl MyContainer for MyStorage {
    fn items<'a>(&'a self) -> Box<Iterator<Item = &'a MyTrait> + 'a> {
        Box::new(self.0.iter())
    }
}

这会导致以下编译器错误:

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, MyStruct> as std::iter::Iterator>::Item == &MyTrait`
  --> src/main.rs:12:9
   |
12 |         Box::new(self.0.iter())
   |         ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `MyStruct`, found trait MyTrait
   |
   = note: expected type `&MyStruct`
              found type `&MyTrait`
   = note: required for the cast to the object type `std::iter::Iterator<Item=&MyTrait>`

我的理解是,尽管&MyStruct通常可以转换为&MyTrait,但在这种情况下,标准库的Iterator实现并不允许它。 请注意,相同的构造适用于Vec<Box<MyStruct>>Iterator<Item=&Box<MyTrait>>,但拳击在这里并不合适。

有没有办法让这个工作用引用?

1 个答案:

答案 0 :(得分:7)

您需要明确地转换单个元素,如下所示:

Box::new(self.0.iter().map(|e| e as &MyTrait))