I have a trait with optional behavior, and I'm trying to figure out how to use it behind a trait object.
trait Trait { fn required_behavior(&self); fn optional_behavior(&self) where Self: Optional; } trait Optional: Trait {} Unfortunately, this trait is not dyn compatible. If I change the bound to Self: Optional + Sized then it is dyn compatible, but the optional_behavior method is understandably non-dispatchable.
If I move the optional method to the subtrait:
trait Trait { fn required_behavior(&self); } trait Optional: Trait { fn optional_behavior(&self); } then the trait is dyn compatible, but I need some way to determine whether the Trait is also Optional, and if so downcast a &dyn Trait to a &dyn Optional. OO languages provide a way to downcast, but AFAIK Rust does not.
I could provide a way to access the downcasted subtrait object from the supertrait:
trait Trait { fn required_behavior(&self); fn as_optional(&self) -> Option<&dyn Optional> { None } } trait Optional: Trait { fn optional_behavior(&self); } However, this is a bit awkward and feels non-idiomatic. (Iterator doesn't do this for DoubleEndedIterator, so rev() is unusable behind dyn Iterator AFAIK.)
Is there a better way?
6 posts - 4 participants
