0
0
Rustprogramming~5 mins

Trait objects overview in Rust

Choose your learning style9 modes available
Introduction

Trait objects let you use different types in the same place if they share some behavior. This helps write flexible and reusable code.

When you want to store different types that implement the same trait in one collection.
When you want to write functions that accept any type with certain behavior without knowing the exact type.
When you want to call methods on types dynamically at runtime instead of compile time.
When you need to hide the concrete type details but keep the ability to use trait methods.
Syntax
Rust
let obj: &dyn TraitName = &value;
let boxed_obj: Box<dyn TraitName> = Box::new(value);

dyn TraitName means a trait object for the trait TraitName.

You can use references &dyn TraitName or smart pointers like Box<dyn TraitName>.

Examples
Use a reference to a trait object to call a method on a value of unknown concrete type but known behavior.
Rust
trait Speak {
    fn speak(&self);
}

struct Dog;
impl Speak for Dog {
    fn speak(&self) {
        println!("Woof!");
    }
}

fn main() {
    let dog = Dog;
    let speaker: &dyn Speak = &dog;
    speaker.speak();
}
Store different drawable shapes in a vector using boxed trait objects.
Rust
trait Draw {
    fn draw(&self);
}

struct Circle;
impl Draw for Circle {
    fn draw(&self) {
        println!("Drawing a circle");
    }
}

fn main() {
    let shapes: Vec<Box<dyn Draw>> = vec![Box::new(Circle)];
    for shape in shapes {
        shape.draw();
    }
}
Sample Program

This program shows how to use trait objects to call the same method on different types that implement the Animal trait.

Rust
trait Animal {
    fn sound(&self);
}

struct Cat;
impl Animal for Cat {
    fn sound(&self) {
        println!("Meow");
    }
}

struct Dog;
impl Animal for Dog {
    fn sound(&self) {
        println!("Woof");
    }
}

fn make_sound(animal: &dyn Animal) {
    animal.sound();
}

fn main() {
    let cat = Cat;
    let dog = Dog;

    let animals: Vec<&dyn Animal> = vec![&cat, &dog];

    for animal in animals {
        make_sound(animal);
    }
}
OutputSuccess
Important Notes

Trait objects use dynamic dispatch, which means the method to call is decided at runtime.

You cannot use trait objects with traits that have generic methods or associated constants.

Use dyn keyword to clearly mark trait objects since Rust 2018 edition.

Summary

Trait objects let you work with different types through a common interface.

They enable dynamic dispatch to call methods at runtime.

Use references or smart pointers with dyn Trait to create trait objects.