How to iterate over a collection of structures as an iterator of references to objects of objects?

I have a set of struct objects. I would like to iterate over a collection using an iterator of feature objects, but I cannot create a suitable iterator for this. My reduced test code:

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

As a result, the following compiler error occurs:

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>`

I understand that although it is &MyStructusually converted to &MyTrait, the implementation of the standard library Iteratorin this case does not allow. Please note: the same design works with Vec<Box<MyStruct>>and Iterator<Item=&Box<MyTrait>>, but boxing is not needed here.

Is there any way to make this work with links?

+4
source share
1 answer

You need to explicitly specify the individual elements, for example:

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

Source: https://habr.com/ru/post/1688868/


All Articles