什么是相当于C++的虚函数的Rust?

use*_*861 3 oop traits rust

我正在尝试在Rust中实现类似于类中的C++虚函数的东西,我会有一个带有数据的基础结构,然后我会保留一些未定义的函数,如下例所示:

class A {
    int stuff;
public:
    virtual void foo(int a, int b) = 0;
    void function_that_calls_foo() { /*...*/ foo(1, 2); /*...*/ }
}

class B: public A { void foo(int a, int b) { /* ... */ } }
Run Code Online (Sandbox Code Playgroud)

我试图使用函数指针实现它,但没有太大的成功.我可以使用具有A函数的特征,并在另一个类上实现A,但是我会丢失struct的数据.什么是最好的(最快?)方式在Rust中实现这种东西?

struct A {
    ...
}

impl A {
    fn function_that_calls_foo(&self) {
        ...
        self.foo(a, b);
        ...
    }
}

struct B {
    a: A;
}

impl B {
    fn xxx(&self) {
        a.function_that_calls_foo(1, 2);
    }

    fn foo(&self, a: i32, b: i32) {...}
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 5

保持一些功能未定义

我正在添加隐式"并且有一些函数调用该待定义函数".

正如E_net4所说,使用特征:

trait Foo {
    fn foo(&self, a: i32, b: i32) -> i32;

    fn function_that_calls_foo(&self) {
        println!("{}", self.foo(1, 2));
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以实现以下特征Base:

struct Base {
    stuff: i32,
}

impl Foo for Base {
    fn foo(&self, a: i32, b: i32) -> i32 {
        self.stuff + a + b
    }
}
Run Code Online (Sandbox Code Playgroud)

正如Matthieu M.所说,Rust没有继承,所以使用组合:

struct Base {
    stuff: i32,
}

impl Base {
    fn reusable(&self) -> i32 {
        self.stuff + 1
    }
}

struct Alpha {
    base: Base,
    modifier: i32,
}

impl Foo for Alpha {
    fn foo(&self, a: i32, b: i32) -> i32 {
        (self.base.reusable() + a + b) * self.modifier
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以通过采用受类型参数约束的泛型来组合这两个概念.


我强烈反对迪特里希·埃普的观点.使用新语言应该涉及检查新的范例.出于代码重用的目的,继承通常不是一个好主意,即使在支持它的语言中也是如此.相反,创建较小的构建块并将它们组合在一起.

  • 你的答案中最重要的部分是:"在我看来,使用一种新语言应该涉及检查新的范例".经常忘记. (3认同)
  • @YuriFeldman 问题是关于 C++ _virtual_ 函数,它没有可重用的代码。 (2认同)
  • 不使用继承进行代码重用根本不是 Rust 特有的,也可以应用于 C++(甚至许多指南都鼓励这样做)。您可以在 C++ 中拥有纯接口,并且还可以以模板的形式拥有编译时多态性。诚然,这一切都有点毛茸茸的,但它就在那里,并且没有任何“新范式”或涉及的东西。 (2认同)