patternrustModerate
Trait objects (dyn Trait): runtime polymorphism in Rust
Viewed 0 times
dyntrait objectvtabledynamic dispatchBoxpolymorphismobject safe
Error Messages
Problem
Developers want to store different types implementing the same trait in a collection or return one of several concrete types from a function.
Solution
Use Box<dyn Trait> for heap-allocated trait objects with dynamic dispatch:
trait Animal {
fn sound(&self) -> &str;
fn name(&self) -> &str;
}
struct Dog;
struct Cat;
impl Animal for Dog {
fn sound(&self) -> &str { "woof" }
fn name(&self) -> &str { "dog" }
}
impl Animal for Cat {
fn sound(&self) -> &str { "meow" }
fn name(&self) -> &str { "cat" }
}
// Vec of different types sharing a trait
let animals: Vec<Box<dyn Animal>> = vec![
Box::new(Dog),
Box::new(Cat),
];
for a in &animals {
println!("{} says {}", a.name(), a.sound());
}
// Returning a trait object
fn make_animal(kind: &str) -> Box<dyn Animal> {
match kind {
"dog" => Box::new(Dog),
_ => Box::new(Cat),
}
}Why
dyn Trait uses a vtable (pointer to a table of function pointers) for runtime dispatch. This enables heterogeneous collections and open-ended polymorphism at the cost of one pointer indirection per call.
Gotchas
- Not all traits are 'object safe' — traits with generic methods or methods returning Self cannot be used as dyn Trait
- dyn Trait has a runtime cost (vtable lookup) vs generics which are zero-cost (monomorphized at compile time)
- Use impl Trait in function parameters for static dispatch, dyn Trait for dynamic dispatch
Revisions (0)
No revisions yet.