From https://doc.rust-lang.org/rust-by-example/trait/dyn.html, as known, the dyn trait's size is not known when compiling, so we can not use it as a return value. But when can create a reference and put it in box, the box has fixed size.
But I met a problem, how can I box a tait which has an interface to consume it.
#[tokio::test]
async fn test_dyn_trait() {
trait Consume {
fn usage(self) -> String;
}
trait Refer {
fn usage(&self) -> String;
}
struct Man {
name: String,
}
impl Consume for Man {
fn usage(self) -> String {
let Man { name } = self;
return name;
}
}
impl Refer for Man {
fn usage(&self) -> String {
return self.name.clone();
}
}
let a: Box<dyn Consume> = Box::new(Man {
name: "aaron".to_string(),
});
let b: Box<dyn Refer> = Box::new(Man {
name: "aaron".to_string(),
});
println!("a: {}", a.usage()); // cannot move a value of type dyn Consume: the size of dyn Consume cannot be statically determined
println!("b: {}", b.usage()); // it is ok
}
This is impossible. Rust has something called object safety, which prevent creating trait objects of traits that have a method that either takes or returns Self
(and couple other things).