我想了解如何使用带有关联类型的trait实现多态。考虑下面的trait:
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>`
但在此情况下,我不能仅仅遵循错误消息,因为实现特质
Animal
的struct
数量不应该是静态的。那么解决这个问题的 Rust 方法是什么呢?提前致谢!
enum Food { Meat, Herb }
和一个fn food(&self) -> Food
。 - eggyalMeat
和Herb
转换为枚举。 这是一个最小的可复制示例,在实际情况中这些是非常复杂的结构体。 我的问题不是关于改编代码,而是关于在Rust中使用具有关联类型的多态向量的总体情况。 但也许我误解了你的回答。 - LoheekFood
确实是问题所在。而且,你一开始就没有多态性,因为Animal
或者说dyn Animal
,正如编译器所告诉你的那样,是一个明确、具体的类型。当你给它添加了一个关联类型时,它变成了一个无限集合的dyn Animal<Food = T>
类型。 - Ivan Cdyn
的特质对象仍然可以在我的版本中使用。但是感谢您提醒我,这将被弃用。然而问题仍然存在,我无法删除关联类型,并且我想要一个唯一的anything.talk()
。因此,如果我理解正确,您是在告诉我在 Rust 中基本上不可能实现这一点。 - Loheek