What is the difference between a Trait and object that impl Trait

Hi

what is the the difference between accepting a trait as argument to accepting a generic that implements a trait?

use std::fmt::Debug;

fn bar(obj: &Debug){
    println!("bar {:#?}",obj);
}

fn foo<T: Debug>(obj: &T) {
    println!("foo {:#?}",obj);
}

fn main() {
    let a = 5;
    foo(&a);
    bar(&a);
}

<T: Debug> uses static dispatch while &Debug uses a trait object. The difference is explained on the Trait Objects page of the book.

So what makes a method object-safe? Each method must require that Self: Sized or all of the following:

Should it be "must not" or am I too tired to get what they're saying?

I think the wording in the book is correct. The methods that require Self: Sized cannot be called on the trait object, but the trait is still object-safe.

trait Trait {
    fn a(&self) {} // ok
    //fn b<T>(&self, T) {} // not ok, uses type parameter
    //fn c(&self, Self) {} // not ok, uses Self
    fn d<T>(&self, T) where Self: Sized {} // ok, uses type parameter but Self: Sized
    fn e(&self, Self) where Self: Sized {} // ok, uses Self but Self: Sized
}

struct Test;
impl Trait for Test {}

fn main() {
    let x: &Trait = &Test;
    x.a();
    //x.d(0); // cannot be called because Trait is not Sized
}

Playground link: Rust Playground

1 Like