Наследование ржавчины: вызов родительского метода

Как Rust вызывает "родительский метод"? Как это в Java:

public class parent{
    ...
    public void doSomething(){
        System.out.println("Parent method");
    }
}
public class child extends parent{
    ...
    public void doSomething(){
        super.doSomething();
        System.out.println("Child method.");
    }
}

В Go, мы можем имитировать его анонимными полями в struct:

type parent struct{}

func (self *parent) doSomething() {
    fmt.Println("parent method")
}

type child struct {
    parent
}

func (self *child) doSomething() {
    self.parent.doSomething()
    fmt.Println("child method")
}
func main() {
    var c1 child
    c1.doSomething()
}

Как имитировать его в ржавчине? Спасибо!

Ответ 1

Это не совсем то же самое под капотом, но что-то вроде

trait DoThings {
    fn do_something(&self); 
}

struct Parent;

impl DoThings for Parent {
    fn do_something(&self) { println("doing something"); }
}

struct Child {
    parent: Parent
}

impl DoThings for Child {
    fn do_something(&self) { 
        self.parent.do_something();
        println("child");
    }
}

fn main() {
    let c = Child { parent: Parent };
    c.do_something();
}

Есть несколько предложений для создания частей этого автоматического (например, если мы хотим просто вызвать родительский метод напрямую, т.е. не переопределять метод в дочернем элементе, то в настоящее время нужно явно вызвать родительский метод).

Ответ 2

Точка наследования может перезаписывать унаследованный метод. Образцы, представленные выше, по-прежнему связаны с делегированием, а не с наследованием.

Давайте посмотрим на некоторый код Go, чтобы проиллюстрировать это:

type Base struct {}
func (Base) Magic() { fmt.Print("base magic") }
func (self Base) MoreMagic() {
  self.Magic()
}

type Foo struct {
  Base
}

func (Foo) Magic() { fmt.Print("foo magic") }

Если вы выполните код выше этого пути

f := new(Foo)
f.Magic()

он напечатает "foo magic" на консоли, а не "базовую магию". Однако, если мы запустим этот код

f := new(Foo)
f.MoreMagic()

он также не будет печатать "foo magic", но на этот раз "базовая магия". Это происходит из-за отсутствия наследования и, следовательно, невозможности перезаписывать метод Magic (иначе говоря, динамическое связывание). Поэтому мы все еще имеем дело с делегацией.

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