It depends a lot on your use case. Usually it gets tricky when you 1: can only find out what the type is at runtime or 2: needs too store different types in a Vec or something.
Outiside of these cases, generics will work just fine.
PS: if you don't need to own the value, you can pass a reference to a &dyn Trait, without needing a box, otherwise you are stuck with it.
PS2: You can probably trade all the Box::new calls for my_type.into(), I think Box implements the From trait dor just about everything, but Im not sure on that one.
Variant enums should be the right way to use polymorphism. Enum variants can have different fields associated with them, and while variants cannot have the methods of their own, enum itself does have methods and can match self in them.
enum Figure {
Circle { r: f64 },
Rectangle { width: f64, height: f64 },
}
impl Figure {
/// Computes the area of the figure.
fn area(&self) -> f64 {
match self {
Figure::Circle { r } => std::f64::consts::PI * r * r,
Figure::Rectangle { width, height } => width * height,
}
}
}
fn main() {
let c = Figure::Circle { r: 2.0 };
let r = Figure::Rectangle { width: 3.0, height: 4.0 };
println!("Circle area: {}", c.area());
println!("Rectangle area: {}", r.area());
}
Fields of variant enums can also be other variant enums, making possible for a lot of polymorphism.
You can even write and read variant enums to/from YAML.