Challenge 2: Printing a Heterogeneous Slice — Possible Solution ==================================================================== fn print_all(items: &[Box]) { for item in items { println!("{}", item); } } fn main() { let items: Vec> = vec![ Box::new(42_i32), Box::new(String::from("hello")), Box::new(3.14_f64), ]; print_all(&items); } WHY THIS WORKS AS AN ANSWER ------------------------------ print_all takes &[Box] — a slice of trait objects, exactly this chapter's dyn Trait pattern. Each element is a Box wrapping SOME concrete type that implements Display, but the function itself never needs to know or care which concrete type any particular element actually is. The Vec literal mixes three genuinely different concrete types — i32, String, and f64 — each individually boxed as dyn std::fmt::Display. This is precisely the heterogeneous-collection capability this chapter highlighted as something monomorphized generics cannot provide: a Vec could only ever hold ONE of these three types, never all three together, but Vec> unifies them all behind the one shared trait. Inside print_all, println!("{}", item) works because {} formatting just needs Display, and dynamic dispatch (via each box's vtable) resolves, at RUNTIME, to whichever concrete type's fmt implementation actually applies to that specific boxed value — i32's Display for the first element, String's for the second, f64's for the third — all through the exact same loop body, with no branching or type-checking code written by hand.