在 trait impls 中重用默认方法实现

pyo*_*yon 1 traits rust

在 C++ 中,重写的虚成员函数可以调用其基类中定义的版本:

struct foo {
  virtual void run() {
    printf("printf yeah!\n");
  }
};

struct bar : foo {
  void run() {
    foo::run();
    std::cout << "un-cout-h!" << std::endl;
  }
};
Run Code Online (Sandbox Code Playgroud)

我想在 Rust 中做类似的事情。我有一个包含默认方法定义的特征,我想在那些方法被覆盖的 impls 中重用这些定义:

trait Foo {
    fn run(&self) {
        // do something
    }
}

impl Foo for Bar {
    fn run(&self) {
        // call default implementation of Foo::run()
        // run custom logic
    }
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?


编辑:建议的解决方案并不完全令人满意。一旦我覆盖了一个方法,我打算覆盖的实现不能被第三方使用。

DK.*_*DK. 5

你没有。

首先,Rust 没有像 C++ 那样的子类化。 Foo::run不是一种以你可以称之为的方式存在的东西。该方法主体仅在您Foo为类型实现并且不提供该run方法的实现时使用。它被编译器有效地复制+粘贴到每个impl需要它的地方。

其次,这两个例子没有可比性,因为你已经从根本上改变了含义。在 C++ 的情况下,您正在定义一个实例方法。在 Rust 的情况下,您正在定义一个静态方法。Rust 中的实例方法需要一个显式self参数。即使事实并非如此,它也不会改变第一点。

如果你想提供一些通用的功能,你需要把它写在别处。最简单的方法是使用像这样的自由函数:

trait Foo {
    fn run(&mut self) {
        println!("Foo::run()");
    }
}

fn run_base(foo: &mut Foo) {
    println!("run_base()");
}

struct Bar;

impl Foo for Bar {
    fn run(&mut self) {
        run_base(self);
        println!("Bar::run()");
    }
}

fn main() {
    let mut bar = Bar;
    bar.run();
}
Run Code Online (Sandbox Code Playgroud)