属于特征的对象的向量 [英] Vector of objects belonging to a trait

查看:76
本文介绍了属于特征的对象的向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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(类型不匹配)时,编译器告诉我vAnimal的向量

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是特征,并且特征没有大小(不能保证CatDog具有相同的大小).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆