A trait object is a way to use traits for dynamic dispatch, allowing you to call methods on types that implement a trait without knowing the exact type at compile time.
Click to reveal answer
beginner
How do you create a trait object in Rust?
You create a trait object by using a reference or a pointer to a type that implements a trait, like &dyn Trait or Box<dyn Trait>.
Click to reveal answer
intermediate
Why use trait objects instead of generics?
Trait objects allow for dynamic dispatch and can store different types that implement the same trait in one variable, while generics use static dispatch and require knowing the type at compile time.
Click to reveal answer
intermediate
What is dynamic dispatch in the context of trait objects?
Dynamic dispatch means the program decides at runtime which method implementation to call based on the actual type behind the trait object.
Click to reveal answer
advanced
Can trait objects be used with traits that have generic methods?
No, trait objects cannot be created from traits with generic methods because the compiler needs to know the exact types to perform dynamic dispatch.
Click to reveal answer
Which syntax correctly creates a trait object for a trait named `Draw`?
A&dyn Draw
B&Draw
CBox<Draw>
Ddyn &Draw
✗ Incorrect
The correct syntax for a trait object reference is &dyn Trait, so &dyn Draw is correct.
What does dynamic dispatch mean when using trait objects?
AChoosing method implementation at runtime
BChoosing method implementation at compile time
CInlining all methods
DUsing generics for performance
✗ Incorrect
Dynamic dispatch means the program decides which method to call at runtime based on the actual type.
Why can't trait objects be used with traits that have generic methods?
ABecause trait objects only support static dispatch
BBecause trait objects only work with structs
CBecause generic methods are slower
DBecause generic methods require knowing exact types at compile time
✗ Incorrect
Generic methods require the compiler to know exact types, which trait objects cannot provide for dynamic dispatch.
Which of these is a benefit of using trait objects?
AEnable compile-time type checking only
BStore different types implementing the same trait in one variable
CAvoid runtime overhead
DMake code run faster than generics
✗ Incorrect
Trait objects allow storing different types that implement the same trait in one variable using dynamic dispatch.
What is the main difference between trait objects and generics?
AGenerics can only be used with primitive types
BTrait objects are faster than generics
CTrait objects use dynamic dispatch; generics use static dispatch
DTrait objects require knowing types at compile time
✗ Incorrect
Trait objects use dynamic dispatch to decide method calls at runtime, while generics use static dispatch at compile time.
Explain what a trait object is and how it enables dynamic dispatch in Rust.
Think about how Rust calls methods when the exact type is not known at compile time.
You got /3 concepts.
Describe the main differences between using trait objects and generics in Rust.
Consider when you want flexibility versus performance.
You got /4 concepts.
Practice
(1/5)
1. What is the main purpose of using trait objects in Rust?
easy
A. To allow different types to be used through a common interface at runtime
B. To improve compile-time performance by avoiding dynamic dispatch
C. To create new data types that do not implement any traits
D. To statically bind methods to specific types only
Solution
Step 1: Understand trait objects concept
Trait objects let you use different types that implement the same trait through a common interface.
Step 2: Identify dynamic dispatch role
Trait objects enable dynamic dispatch, meaning method calls are decided at runtime, allowing flexibility.
Final Answer:
To allow different types to be used through a common interface at runtime -> Option A
Quick Check:
Trait objects = common interface + runtime dispatch [OK]
Hint: Trait objects enable runtime method calls on different types [OK]
2. Which of the following is the correct syntax to create a trait object reference for a trait named Animal?
easy
A. let a: &Animal = &dog;
B. let a: Animal = &dog;
C. let a: dyn Animal = dog;
D. let a: &dyn Animal = &dog;
Solution
Step 1: Recall trait object syntax
Trait objects require the dyn keyword before the trait name when used as a reference or pointer.
Step 2: Check each option
let a: &dyn Animal = &dog; uses &dyn Animal, which is the correct syntax for a trait object reference.
Final Answer:
let a: &dyn Animal = &dog; -> Option D
Quick Check:
Trait object syntax = &dyn Trait [OK]
Hint: Use &dyn Trait for trait object references [OK]
Common Mistakes:
Omitting the dyn keyword
Trying to use trait name without reference
Assigning trait object without pointer or reference
3. What will be the output of the following Rust code?
trait Speak {
fn speak(&self) -> String;
}
struct Dog;
impl Speak for Dog {
fn speak(&self) -> String {
"Woof".to_string()
}
}
struct Cat;
impl Speak for Cat {
fn speak(&self) -> String {
"Meow".to_string()
}
}
fn animal_speak(animal: &dyn Speak) {
println!("{}", animal.speak());
}
fn main() {
let dog = Dog;
let cat = Cat;
animal_speak(&dog);
animal_speak(&cat);
}
medium
A. Woof\nMeow
B. Dog\nCat
C. Woof\nWoof
D. Compilation error due to trait object usage
Solution
Step 1: Understand trait implementations
Dog and Cat both implement the Speak trait with their own speak() returning "Woof" and "Meow" respectively.
Step 2: Analyze function calls with trait objects
animal_speak takes a reference to a dyn Speak trait object and calls speak(), which uses dynamic dispatch to call the correct method.
Final Answer:
Woof\nMeow -> Option A
Quick Check:
Dynamic dispatch calls correct speak() = Woof then Meow [OK]
Hint: Trait objects call correct method at runtime [OK]
Common Mistakes:
Expecting static dispatch output
Confusing struct names with method output
Thinking code causes compilation error
4. Identify the error in the following Rust code using trait objects:
trait Draw {
fn draw(&self);
}
struct Circle;
impl Draw for Circle {
fn draw(&self) {
println!("Drawing Circle");
}
}
fn main() {
let c = Circle;
let obj: Box<Draw> = Box::new(c);
obj.draw();
}
medium
A. Circle does not implement Draw trait
B. Missing dyn keyword in Box type declaration
C. Cannot call draw() on Box pointer
D. Box::new() requires a reference, not value
Solution
Step 1: Check trait object syntax in Box
Trait objects require the dyn keyword when used as a pointer type like Box.
Step 2: Identify missing dyn keyword
The code uses Box<Draw> instead of Box, causing a syntax error.
Final Answer:
Missing dyn keyword in Box type declaration -> Option B
Quick Check:
Box trait object needs dyn keyword [OK]
Hint: Always use dyn with trait objects in pointers like Box [OK]
Common Mistakes:
Omitting dyn keyword in trait object types
Assuming trait implementation is missing
Thinking Box cannot call trait methods
5. You want to store different shapes (Circle, Square) in a single vector and call their area() method at runtime. Which approach correctly uses trait objects to achieve this?
trait Shape {
fn area(&self) -> f64;
}
struct Circle { radius: f64 }
struct Square { side: f64 }
impl Shape for Circle {
fn area(&self) -> f64 { 3.14 * self.radius * self.radius }
}
impl Shape for Square {
fn area(&self) -> f64 { self.side * self.side }
}
fn main() {
// Fill in the blank
let shapes: Vec> = vec![
Box::new(Circle { radius: 2.0 }),
Box::new(Square { side: 3.0 }),
];
for shape in shapes.iter() {
println!("Area: {}", shape.area());
}
}
hard
A. Use Vec<&Shape> with references to shapes without Box
B. Use Vec<Shape> directly without pointers
C. Use Vec> with Box::new for each shape
D. Use Vec without Box or references
Solution
Step 1: Understand trait object storage
Trait objects must be stored behind pointers like Box or references because their size is unknown at compile time.
Step 2: Analyze vector type and initialization
Using Vec> with Box::new() for each shape correctly stores different types implementing Shape.
Final Answer:
Use Vec> with Box::new for each shape -> Option C
Quick Check:
Trait objects need pointers like Box in collections [OK]
Hint: Store trait objects in Box pointers inside collections [OK]
Common Mistakes:
Trying to store trait objects directly without pointers
Using Vec<Shape> which is invalid
Using references without ensuring lifetime
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.