#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
больше не выполняется.