我试图了解当使用具有关联类型的特征时多态性是如何工作的。考虑以下特征:
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 解决这个问题的方法是什么?提前致谢
&Animal 是 的缩写 &dyn Animal。dyn Animal是一个特征对象类型,并且仅当特征是对象安全时它才存在于给定的特征中。具有关联类型的特征不是对象安全的,因为如果不指定关联类型dyn Animal就无法实现。\xc2\xb9AnimalFood
这是运行时多态性(特征对象)的固有限制:您不知道具体类型,因此您无法知道其关联类型。\xc2\xb2
\n如果你想创建一个可以调用的东西的向量.talk(),那么很容易为此创建一个特征(playground):
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];\nRun Code Online (Sandbox Code Playgroud)\n您将无法编写任何使用Foodvia a 的代码&dyn Talk,这就是要点:Food取决于具体类型,并且您的向量包含多个具体类型。
\xc2\xb9 您可以创建具有相同关联类型的类型的特征对象,例如dyn Animal<Food = Herb>. 这常见于Iterator,如Box<dyn Iterator<Item = i32>>。Animal但当s 具有不同种类的时,它并不能解决问题Food。
\xc2\xb2 通过编译时多态性(泛型),您可以编写对任何类型实现的Animal任何内容通用的代码Food。但是您不能将不同编译时类型的内容放入 a 中Vec,因此这也没有帮助。
| 归档时间: |
|
| 查看次数: |
1055 次 |
| 最近记录: |