I am trying to understand why the following code does not compile:
trait Vehicle {
fn get_num_wheels(&self) -> u32;
}
impl std::fmt::Display for dyn Vehicle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Has {} wheels", self.get_num_wheels())
}
}
struct Car();
impl Vehicle for Car {
fn get_num_wheels(&self) -> u32 {
4
}
}
fn main() {
let car = Car {};
println!("{car}");
}
error[E0277]: `Car` doesn't implement `std::fmt::Display`
--> src/main.rs:21:16
|
21 | println!("{car}");
| ^^^ `Car` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Car`
I would think that if I implemented Display
for Vehicle
, then all structs that implement Vehicle
would also inherit Vehicle
's implementation of Display
. I can see why this would be an issue if Car
tried to make its own implementation of Display
, but this is not the case here.
I know I can fix this example by changing
impl std::fmt::Display for dyn Vehicle
to
impl std::fmt::Display for Car
but for non-trivial examples, this seems really verbose. What's the right way to do this?
Vehicle::Car(c)
orVehicle::Motorbike(m)
each of wraps another type and can implementDisplay
at a higher level. You could also haveVehicleContainer<V> where V : Vehicle
and thatVehicle
is some kind of trait as you have here, though the container is what implementsDisplay
. – Thirtyeight