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

2023-12-26

我想了解如何多态性使用时有效具有相关类型的特征。考虑以下特征:

trait Animal {
    fn talk (&self);
}

此特征由以下结构使用:

struct Dog;
struct Cow;

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

impl Animal for Cow {
    fn talk (&self) {
        println!("Moo");
    }
}

然后我循环一个Vec<&Animal>,多态性在这里效果很好:

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

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

struct Meat;
struct Herb;

trait Animal {
    type Food;
    ...
}
impl Animal for Dog {
    type Food = Meat;
    ...
}
impl Animal for Cow {
    type Food = Herb;
    ...
}

现在我收到错误:

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>`

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

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


&Animal 是缩写 https://stackoverflow.com/questions/50650070/what-does-dyn-mean-in-a-type &dyn Animal. dyn Animal is a 特质对象类型,并且仅当特征是给定特征时它才存在对象安全 https://doc.rust-lang.org/book/ch17-02-trait-objects.html#object-safety-is-required-for-trait-objects。具有关联类型的特征不是对象安全的,因为dyn Animal无法实施Animal不指定关联类型Food

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

如果你想创建一个向量,你可以调用.talk()就这样,很容易为此创建一个特征():

trait Talk {
    fn talk(&self);
}

impl<A: Animal> Talk for A {
    fn talk(&self) {
        Animal::talk(self);
    }
}

let animals: Vec<&dyn Talk> = vec![&Dog, &Cow];

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

See also

  • 为什么特征内的通用方法需要调整特征对象的大小? https://stackoverflow.com/q/42620022/3650362
  • 是什么让某物成为“特质对象”? https://stackoverflow.com/q/27567849/3650362
  • 无法创建多态类型,因为该特征无法制成对象 https://stackoverflow.com/q/39412626/3650362

¹ You can创建一个具有所有类型的特征对象the same关联类型,例如dyn Animal<Food = Herb>。这常见于Iterator, as in Box<dyn Iterator<Item = i32>>。但这并不能解决问题Animal有不同种类的Food.

² 通过编译时多态性(泛型),您可以编写对任何实现了泛型的代码通用的代码Animal与任何Food类型。但是你不能将不同编译时类型的东西放在一个Vec,所以这也没有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐