impl Trait:静态分发
dyn Trait:动态分发
静态分发:在编译期就确定了具体返回类型,函数只能返回一种类型。
动态分发:在运行时才能确定具体返回类型,函数可以返回多种类型。
Trait Object:指向trait的指针,假设Animal是一个triait,那么&Animal和Box<Animal>都是一种Trait Object。
胖指针:用于指代动态大小类型(DST)的引用和原始指针(切片或特征对象)。胖指针包含一个指针以及一些使DST完成(例如长度)的信息。
返回值为impl Trait时用dyn Trait是没问题的
trait Animal { fn get_kind(&self) -> String; fn default_impl(&self) { println!("default impl"); } } impl dyn Animal { fn trait_object() { println!("trait object"); } } #[derive(Debug)] struct Dog {} impl Animal for Dog { fn get_kind(&self) -> String { "Dog".to_string() } } struct Cat {} impl Animal for Cat { fn get_kind(&self) -> String { "Cat".to_string() } } // 静态分发 fn get_animal_static() -> impl Animal { let x = 1; if x == 1 { Dog {} } else { Dog {} } } // 动态分发 fn get_animal_dyn() -> Box<dyn Animal> { let x = 0; if x == 1 { Box::new(Dog {}) } else { Box::new(Cat {}) } } fn main() { let dog = Dog {}; dog.default_impl(); let cat = Cat {}; cat.default_impl(); // 只有 trait objects 才能调用 // dog.trait_object(); // cat.trait_object(); <dyn Animal>::trait_object(); let _ = &<dyn Animal>::trait_object(); let animal = get_animal_static(); // Dog println!("{}", animal.get_kind()); let animal = get_animal_dyn(); // Cat println!("{}", animal.get_kind()); }