Need Help With Traits and Iterators (Beginner)

I'm relatively new to rust, so I'm not completely familiar with the way traits and iterators work. I'm trying to make an entity component system, but I keep getting stuck on this "get_components" method. It's meant to return an iterator for a specific type of component, which a system can then use to update the components.

pub fn get_components<T: Component>(&self) -> Option<IterMut<Option<&mut T>>> {
    match self.components.get_mut(&TypeId::of::<T>()) {
        Some(components) => Some(components.iter_mut().map(|slot| match slot {
            Some(component) => component.downcast_mut::<T>(),
            None => None,
        })),
        None => None,
    }
}

The components HashMap looks like this:

components: HashMap<TypeId, Vec<Option<Box<dyn Any>>>>,

The error that I'm getting says:

"mismatched types
expected struct `std::slice::IterMut<'_, Option<&mut T>>`
   found struct `Map<std::slice::IterMut<'_, Option<Box<(dyn Any + 'static)>>>, [closure@src\scene.rs:75:64: 75:70]>`"

Any help would really be appreciated!

The .map method of iterators returns a new type
Namely if you map an iterator of type ITER then the result is Map
Using concrete types with iterators is quite advanced and in general, it's easier to just use
Box<dyn Iterator<Item=T>> (called a trait object) rather than specific iterator types.

You can also use impl Iterator<Item=T> and the compiler will unify that type with the concrete type returned by your function. In this case, because your type contains a closure, this is the only way to specify an exact type without using a trait object.

Here's what the return position impl Trait (RPIT) approach could look like.

You can't use RPIT in traits yet, so if this is a trait method, you'll need the boxed approach.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.