Я пытаюсь понять, как работает полиморфизм при использовании характеристики со связанным типом. Обратите внимание на следующую черту:
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>`
Но в этом случае я не могу просто следить за сообщением об ошибке, поскольку количество struct
, реализующих черту Animal
, не должно быть статическим.
Как это решить с помощью Rust? заранее спасибо
enum Food { Meat, Herb }
сfn food(&self) -> Food
в вашей характеристике. - person eggyal   schedule 22.04.2021Meat
иHerb
в перечисления. Это минимальное воспроизведение, на самом деле это очень сложные конструкции. Мой вопрос был не об адаптации кода, а об использовании полиморфных векторов в ржавчине со связанными типами в целом. Но может я неправильно понял твой ответ - person Loheek   schedule 22.04.2021match
, не зная различных типов, чтобы использовать правильную функцию? Это не столько о пользователях, я просто не хочу копировать / вставлять весь список типов везде, когда я добавляю или удаляю тип - person Loheek   schedule 22.04.2021if let
. В противном случае вы можете использоватьmatch
с подстановочным знаком_
для игнорирования вариантов, которые вам не нужны. - person eggyal   schedule 22.04.2021main
я не хочу копировать / вставлять в шаблонmatch
каждый тип, реализующий эту черту, именно поэтому полиморфизм вообще полезен. - person Loheek   schedule 22.04.2021main
? Возможно, вам стоит вместо этого реализовать метод наFood
? - person eggyal   schedule 22.04.2021Food
функции входят в объем этой проблемы, проблема в том, что полиморфизм работает хорошо, у меня естьmain
функция, когда я могу вызвать функцию подтипаtalk()
без копирования / вставки 1435 имен типов животных. Но если у признака есть связанный тип (это не то, что я могу изменить), он больше не работает. Я хотел бы сохранить этотanything.talk()
, который вызывал функцию правильного подтипа, которая сработала в первый раз. Я был бы удивлен, что нет способа сделать это - person Loheek   schedule 22.04.2021Food
действительно проблема здесь. Кроме того, у вас вообще никогда не было полиморфизма, потому чтоAnimal
или, скорее,dyn Animal
, как должен сказать вам компилятор, является определенным, конкретным типом. Когда вы добавляете к нему связанный тип, он вместо этого становится бесконечным наборомdyn Animal<Food = T>
типов. - person Ivan C   schedule 22.04.2021dyn
все еще работают с моей версией. Но спасибо, что напомнили мне, что это не рекомендуется. Однако проблема все та же, я не могу удалить связанный тип и хотел бы иметь уникальныйanything.talk()
. Итак, если я хорошо понимаю, вы говорите мне, что в Rust это в принципе невозможно. - person Loheek   schedule 22.04.2021