Trait Objects - The Rust Programming Language

Let's clarify the terms and concepts related to impl Trait and dyn Trait, and delve deeper into the idea of trait objects.

impl Trait

dyn Trait

Trait Objects

A trait object is a way to work with types that implement a particular trait without knowing the concrete type at compile time. Trait objects are typically used with smart pointers like Box, Rc, or Arc, or with references (& or &mut).

Example:

trait MyTrait {
    fn my_method(&self);
}

struct MyStruct;

impl MyTrait for MyStruct {
    fn my_method(&self) {
        println!("MyStruct's implementation of my_method");
    }
}

fn main() {
    let obj: Box<dyn MyTrait> = Box::new(MyStruct);
    obj.my_method();
}

What Makes a Trait Object a Trait Object?

A trait object is formed when you use the dyn keyword to create a type-erased reference or smart pointer to a type that implements a trait. This type erasure allows different types to be treated uniformly based on the trait they implement.

Trait Bounds with impl Trait and dyn Trait

Trait bounds are constraints that specify that a type must implement a particular trait. You can use trait bounds with both impl Trait and dyn Trait.

Using impl Trait with Trait Bounds