具有关联类型的多态结构向量

Loh*_*eek 3 polymorphism rust

我试图了解当使用具有关联类型的特征时多态性是如何工作的。考虑以下特征:

trait Animal {
    fn talk (&self);
}
Run Code Online (Sandbox Code Playgroud)

此特征由以下结构使用:

struct Dog;
struct Cow;

impl Animal for Dog {
    fn talk (&self) {
        println!("Woof");
    }
}

impl Animal for Cow {
    fn talk (&self) {
        println!("Moo");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我循环 a Vec<&Animal>,多态性在这里工作得很好:

fn main() {
    let animals: Vec<&Animal> = vec![&Dog, &Cow];
    for animal in &animals {
        animal.talk();
    }
}
// output:
// Woof
// Moo
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。现在,我向特征添加一个关联类型 Food(该类型未使用,但仅用于最小重现)。

struct Meat;
struct Herb;

trait Animal {
    type Food;
    ...
}
impl Animal for Dog {
    type Food = Meat;
    ...
}
impl Animal for Cow {
    type Food = Herb;
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在我收到错误:

error[E0191]: the value of the associated type `Food` (from trait `Animal`) must be specified
   --> src/main.rs:188:23
163 |     type Food;
    |     ---------- `Food` defined here
...
188 |     let animals: Vec<&Animal> = vec![&Dog, &Cow];
    |                       ^^^^^^ help: specify the associated type: `Animal<Food = Type>`
Run Code Online (Sandbox Code Playgroud)

struct但在这种情况下,我不能只关注错误消息,因为实现该特征的 s 数量Animal不应该是静态的。

Rust 解决这个问题的方法是什么?提前致谢

tre*_*tcl 7

&Animal 是 的缩写 &dyn Animaldyn Animal是一个特征对象类型,并且仅当特征是对象安全时它才存在于给定的特征中。具有关联类型的特征不是对象安全的,因为如果不指定关联类型dyn Animal就无法实现。\xc2\xb9AnimalFood

\n

这是运行时多态性(特征对象)的固有限制:您不知道具体类型,因此您无法知道其关联类型。\xc2\xb2

\n

如果你想创建一个可以调用的东西的向量.talk(),那么很容易为此创建一个特征(playground):

\n
trait Talk {\n    fn talk(&self);\n}\n\nimpl<A: Animal> Talk for A {\n    fn talk(&self) {\n        Animal::talk(self);\n    }\n}\n\nlet animals: Vec<&dyn Talk> = vec![&Dog, &Cow];\n
Run Code Online (Sandbox Code Playgroud)\n

您将无法编写任何使用Foodvia a 的代码&dyn Talk,这就是要点:Food取决于具体类型,并且您的向量包含多个具体类型。

\n

也可以看看

\n\n
\n

\xc2\xb9 您可以创建具有相同关联类型的类型的特征对象,例如dyn Animal<Food = Herb>. 这常见于Iterator,如Box<dyn Iterator<Item = i32>>Animal但当s 具有不同种类的时,它并不能解决问题Food

\n

\xc2\xb2 通过编译时多态性(泛型),您可以编写对任何类型实现的Animal任何内容通用的代码Food。但是您不能将不同编译时类型的内容放入 a 中Vec,因此这也没有帮助。

\n


归档时间:

查看次数:

1055 次

最近记录:

4 年,8 月 前