属于特征的对象的向量 [英] Vector of objects belonging to a trait
问题描述
考虑以下代码:
trait Animal {
fn make_sound(&self) -> String;
}
struct Cat;
impl Animal for Cat {
fn make_sound(&self) -> String {
"meow".to_string()
}
}
struct Dog;
impl Animal for Dog {
fn make_sound(&self) -> String {
"woof".to_string()
}
}
fn main () {
let dog: Dog = Dog;
let cat: Cat = Cat;
let v: Vec<Animal> = Vec::new();
v.push(cat);
v.push(dog);
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
当我尝试推动cat
(类型不匹配)时,编译器告诉我v
是Animal
的向量
The compiler tells me that v
is a vector of Animal
when I try to push cat
(type mismatch)
那么,如何创建属于特征的对象的向量并在每个元素上调用相应的trait方法?
So, how can I make a vector of objects belonging to a trait and calls the corresponding trait method on each element?
推荐答案
Vec<Animal>
是不合法的,但是编译器无法告诉您,因为类型不匹配会以某种方式将其隐藏.如果我们删除对push
的调用,则编译器会给我们以下错误:
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();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
之所以不合法,是因为Vec<T>
在内存中连续存储了许多T
对象.但是,Animal
是特征,并且特征没有大小(不能保证Cat
和Dog
具有相同的大小).
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).
要解决此问题,我们需要在Vec
中存储具有一定大小的内容.最直接的解决方案是将值包装在 Box
,即Vec<Box<Animal>>
. Box<T>
具有固定大小(如果T
是特征,则为胖指针",否则为简单指针).
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).
这是正在工作的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());
}
}
这篇关于属于特征的对象的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!