Vec<Animal>
is not legal, but the compiler can't tell you that because the type mismatch somehow hides it. If we remove the calls to push
, the compiler gives us the following error:
<anon>:22:9: 22:40 error: instantiating a type parameter with an incompatible type `Animal`, which does not fulfill `Sized` [E0144]
<anon>:22 let mut v: Vec<Animal> = Vec::new();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The reason why that's not legal is that a Vec<T>
stores many T
objects consecutively in memory. However, Animal
is a trait, and traits have no size (a Cat
and a Dog
are not guaranteed to have the same size).
To solve this problem, we need to store something that has a size in the Vec
. The most straightforward solution is to wrap the values in a Box
, i.e. Vec<Box<Animal>>
. Box<T>
has a fixed size (a "fat pointer" if T
is a trait, a simple pointer otherwise).
Here's a working main
:
fn main() {
let dog: Dog = Dog;
let cat: Cat = Cat;
let mut v: Vec<Box<Animal>> = Vec::new();
v.push(Box::new(cat));
v.push(Box::new(dog));
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…