Ошибка при попытке реализовать функцию, объявленную в supertrait

#rust #traits

Вопрос:

Я пытаюсь реализовать признак, который имеет supertrait, например:

 trait A {
    fn do_a(amp;self);
}

trait B: A {
    fn do_b(amp;self);
}

struct S {}

impl B for S {
    fn do_a(amp;self) {}
    fn do_b(amp;self) {}
}
 

Когда я запускаю сборку cargo, я получаю эти ошибки компилятора:

 error[E0407]: method `do_a` is not a member of trait `B`
  --> src/example.rs:12:5
   |
12 |     fn do_a(amp;self) {}
   |     ^^^^^^^^^^^^^^^^^ not a member of trait `B`

error[E0277]: the trait bound `example::S: example::A` is not satisfied
  --> src/example.rs:11:6
   |
5  | trait B: A {
   |          - required by this bound in `example::B`
...
11 | impl B for S {
   |      ^ the trait `example::A` is not implemented for `example::S`
 

Я продолжаю перечитывать о supertraits, но у меня возникают проблемы с пониманием этой ошибки.

  • Кажется, что первая ошибка противоречит тому, что trait B: A говорит программе делать.
  • Вторая ошибка, по-видимому, противоречит тому, что реализация do_a(amp;self) {} удовлетворяет A .

Чего мне здесь не хватает? Ошибочна ли моя ментальная модель, или в моем коде отсутствует какой-то необходимый шаблон, или и то, и другое?

Ответ №1:

Я считаю, что синтаксис больше связан с ограничением типа (например, тип T , который реализует, обязательно B должен реализовывать A ), чем наследование в объектно-ориентированном смысле. Если вы выписываете impl s отдельно, он компилируется нормально:

 trait A {
    fn do_a(amp;self);
}

trait B: A {
    fn do_b(amp;self);
}

struct S {}

impl A for S {
    fn do_a(amp;self) {}
}

impl B for S {
    fn do_b(amp;self) {}
}
 

Игровая площадка

Примечание: если вы удалите impl for A , код больше не компилируется, ограничение, которое impl B должно выполняться, также impl A больше не выполняется.