使用 dyn
返回 Trait
Rust 编译器需要知道每个函数的返回类型需要多少空间。这意味着你所有的函数都必须返回一个具体的类型。与其他语言不同,如果你有一个像 Animal
这样的 trait,你不能编写一个返回 Animal
的函数,因为它的不同实现需要不同大小的内存。
但是,有一个简单的解决方法。我们的函数不是直接返回 trait 对象,而是返回一个 Box
,它*包含*一些 Animal
。Box
只是一个指向堆内存的引用。因为引用具有静态已知的大小,并且编译器可以保证它指向堆分配的 Animal
,所以我们可以从我们的函数返回一个 trait!
当 Rust 在堆上分配内存时,它会尽可能地明确。所以如果你的函数以这种方式返回一个指向堆上 trait 的指针,你需要使用 dyn
关键字来编写返回类型,例如 Box<dyn Animal>
。
struct Sheep {} struct Cow {} trait Animal { // Instance method signature fn noise(&self) -> &'static str; } // Implement the `Animal` trait for `Sheep`. impl Animal for Sheep { fn noise(&self) -> &'static str { "baaaaah!" } } // Implement the `Animal` trait for `Cow`. impl Animal for Cow { fn noise(&self) -> &'static str { "moooooo!" } } // Returns some struct that implements Animal, but we don't know which one at compile time. fn random_animal(random_number: f64) -> Box<dyn Animal> { if random_number < 0.5 { Box::new(Sheep {}) } else { Box::new(Cow {}) } } fn main() { let random_number = 0.234; let animal = random_animal(random_number); println!("You've randomly chosen an animal, and it says {}", animal.noise()); }