There are two ways to "combine traits" in Rust, I believe. I'm wondering what the differences are.
To be concrete, let's say the two traits are Beeps
and Honks
trait Beeps { fn beep(&self); }
trait Honks { fn honk(&self); }
A new empty trait can be formed, as explained here:
impl<T: Beeps + Honks> BeepsAndHonks for T {}
For concreteness, an implementation would just be this:
struct Obj {}
impl Beeps for Obj { fn beep(&self) {} }
impl Honks for Obj { fn honk(&self) {} }
The combined trait can be used like so
fn factory() -> Box<dyn BeepsAndHonks> {
Box::new( Obj {} )
}
The other way to achieve a "combined trait" is via suptertraits:
trait BeepsAndHonks2: Beeps { fn honk(&self); }
This uses Beeps
as a base and layers a honk
on top. (Sorry for all the silly beeping and honking.)
When I don't own Beeps
and Honks
then the new empty trait is the only way to do this (I believe). Otherwise I can do either new empty trait or supertrait. Structurally the two approaches are different, but under the hood there is no difference, e.g. regarding number of vtable lookups, is that correct?
Since traits clearly can be combined, what speaks against allowing the Beeps+Honks
syntax, e.g. fn factory() -> Box<dyn Beeps+Honks>
?