liveBook · Manning

Dynamic dispatch

As explained in Idiomatic Rust

Dynamic dispatch is runtime selection of an implementation based on the concrete type behind an interface value.

Dynamic dispatch selects a trait implementation at runtime. Rust trait objects (`dyn Trait`) use a compiler-generated vtable, letting one collection hold different types that implement the same trait. Because trait objects are unsized, store them through a pointer such as `Box`; `Vec<dyn Trait>` cannot hold them directly. Use dynamic dispatch deliberately: it can be an antipattern in some cases. section 2.2.6

let mut v = Vec::<Box<dyn MyTrait>>::new();

v.push(Box::new(MyStruct1 {}));          #1
v.push(Box::new(MyStruct2 {}));            #2

v.iter().for_each(|i| i.trait_hello());                   #3
// v.iter().for_each(|i| i.struct_hello()); error!    #4

The example stores two concrete types in `Vec<Box<dyn MyTrait>>` and calls their shared trait method. section 2.2.6

How Idiomatic Rust covers it

How deep it goes
Explains `dyn` trait objects, vtable-based lookup, and pointer requirements for unsized values.
Examples
Demonstrates two structs in a boxed trait-object vector and dispatches their shared method.
What you can do after
Build a heterogeneous `Vec<Box<dyn MyTrait>>` and invoke the shared trait method.
How it connects
Connects traits and trait objects to vtables, runtime polymorphism, and virtual methods.

Also explained in

Compare how 2 books explain dynamic dispatch →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Idiomatic Rust. The section links point to the parts of the book it draws on.