In this lesson, you will learn how to choose between static and dynamic dispatch when working with trait-based references in Rust.
When you use a trait as a boundary for your functions, Rust needs to know how to execute the code associated with that trait. You have two primary ways to handle this: Static Dispatch and Dynamic Dispatch.
Static Dispatch (impl Trait or Generics)
Static dispatch happens at compile time. When you write a generic function like fn process<T: Speak>(item: &T), the compiler generates a unique version of that function for every specific type you pass in.
Because the compiler knows exactly which concrete type is being used, it can "inline" the function calls, making it extremely fast. However, this causes "code bloat" because the compiler produces a new copy of the function for every different type used.
Dynamic Dispatch (&dyn Trait)
Dynamic dispatch happens at runtime. When you use a reference like &dyn Speak, you are using a trait object. Rust doesn't know the concrete type of the value at compile time, so it uses a "vtable" (virtual method table).
When you call a method on &dyn Speak, the program looks up the correct function address in that vtable before executing it. This adds a tiny bit of runtime overhead but is much more flexible, as it allows you to store different types in a single collection (like a Vec<&dyn Speak>).
trait Speak {
fn say(&self);
}
// Static Dispatch: The compiler generates specific code for each T
fn static_speak<T: Speak>(item: &T) {
item.say();
}
// Dynamic Dispatch: The code works via a vtable at runtime
fn dynamic_speak(item: &dyn Speak) {
item.say();
}
When to choose?
Use static dispatch by default for maximum performance. Use dynamic dispatch when you need to group different types together in a single structure or when you need to reduce binary size by avoiding repeated code generation for many different types.
Key Takeaway: Static dispatch uses compile-time knowledge for speed via monomorphization, while dynamic dispatch uses trait objects to provide runtime flexibility at the cost of a small lookup overhead.