Static vs Dynamic Dispatch
Trade-offs.
Static vs Dynamic Dispatch is a free Learn Rust Coding lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Two Ways to Dispatch
When you call a trait method, Rust must decide which concrete implementation runs. There are two strategies: static dispatch (decided at compile time) and dynamic dispatch (decided at runtime).
Static Dispatch With Generics
Generic functions use static dispatch. The compiler generates a specialized copy for each concrete type — a process called monomorphization.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
fn print_area<T: Area>(shape: &T) {
println!("{}", shape.area());
}
fn main() {
print_area(&Square { s: 4.0 });
}Monomorphization
For each type you call with, the compiler stamps out a dedicated version of the function. The method call becomes a direct call with no lookup, so it is as fast as hand-written code.
Dynamic Dispatch With dyn
Trait objects use dynamic dispatch. One function handles all types; the method address is found at runtime via a vtable.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
fn print_area(shape: &dyn Area) {
println!("{}", shape.area());
}
fn main() {
print_area(&Square { s: 4.0 });
}The vtable
A trait object is a fat pointer: one part points to the data, the other to a vtable listing the method addresses. Each call indexes into this table.
That extra indirection is the runtime cost.
Speed Trade-off
Static dispatch is faster per call and can be inlined, but generates more machine code. Dynamic dispatch adds a tiny indirection but keeps code size small.
For most apps the difference is negligible; choose based on flexibility.
Code Size Trade-off
Calling a generic function with many types creates many copies, which can bloat the binary. A single dyn function avoids that duplication.
This is why libraries sometimes prefer trait objects internally.
Flexibility Trade-off
Generics force one concrete type per call site, so they cannot hold mixed types in a collection. Trait objects can. If you need a heterogeneous list, dynamic dispatch is the answer.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
struct Rect { w: f64, h: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
impl Area for Rect { fn area(&self) -> f64 { self.w * self.h } }
fn main() {
let shapes: Vec<Box<dyn Area>> = vec![Box::new(Square { s: 2.0 }), Box::new(Rect { w: 3.0, h: 4.0 })];
let total: f64 = shapes.iter().map(|s| s.area()).sum();
println!("{}", total);
}Mixing Both
You can combine them: a generic function might accept impl Trait at the boundary and store values as Box<dyn Trait> internally. Use each where it fits.
A Decision Guide
Quick rules:
- One type per call, hot path? Use generics (static).
- Mixed types in a collection? Use
dyn(dynamic). - Worried about binary size? Lean toward
dyn.
Both Are Zero-Cost Where It Counts
Rust never adds overhead you did not ask for. Generics cost nothing at runtime; trait objects cost only one pointer indirection. You pick the trade-off explicitly.
Quick Check
Test your dispatch knowledge.
Recap
You compared the two dispatch styles:
- Static (generics): monomorphized, fast, larger binary, one type per call
- Dynamic (
dyn): vtable lookup, flexible, smaller code, allows mixed collections - Choose based on flexibility, performance, and binary size needs
Frequently asked questions
Is the “Static vs Dynamic Dispatch” lesson free?
Yes — the full text of “Static vs Dynamic Dispatch” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.
What will I learn in “Static vs Dynamic Dispatch”?
Trade-offs. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Learn Rust Coding?
No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Static vs Dynamic Dispatch” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Learn Rust Coding lesson?
Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining Traits
- Trait Objects and dyn
- Static vs Dynamic Dispatch
- Default Methods