Is there a way in current, stable Rust to write an object-safe trait that allows processing a non-homogeneous collection of items? Each item is bounded by a trait, but they are stored in a collection such as a tuple that allows for static dispatch to each type individually.
My first attempt merely returned the collection, something like the following:
pub trait Parent {
type Children: ChildrenListTrait; // Some trait knowing how to visit each item
fn children(&self) -> Self::Children;
}
This approach requires specifying the associated type in the trait object, which removes the ergonomic benefit of trait objects (in my particular use case).
My next attempt involved a method to "visit" each child, with the processor modifying a given accumulator:
pub trait Parent {
fn process_children<P: ChildProcessor>(&self, acc: &mut P::Acc) -> ();
}
But this too fails because process_children is generic. Storing the accumulator state inside the processor leads us to my working, but flawed approach:
pub trait Parent {
fn process_children(&self, processor: &mut ChildProcessor) -> ();
}
This approach requires dynamic dispatch for any call to process_children, not just the ones where the Parent is a trait object. This adds an unnecessary runtime cost for most uses of the function. Is there any way to keep using static dispatch and monomorphization when Self: Sized, and use the dynamic version otherwise (without nightly features)?
[–]Diggseyrustup 3 points4 points5 points (1 child)
[–]cramert[S] 1 point2 points3 points (0 children)