oop - 是否可以扩展结构中特征的默认方法实现?

标签 oop inheritance rust default traits

在传统的面向对象语言(例如 Java)中,可以通过从重写版本中的父类(super class)调用原始方法来“扩展”继承类中方法的功能,例如:

class A {
    public void method() {
        System.out.println("I am doing some serious stuff!");
    }
}

class B extends A {
    @Override
    public void method() {
        super.method(); // here we call the original version
        System.out.println("And I'm doing something more!");
    }
}

如您所见,在 Java 中,我可以使用 super 关键字从父类(super class)中调用原始版本。我能够获得继承特征的等效行为,但在为结构实现特征时却没有。

trait Foo {
    fn method(&self) {
        println!("default implementation");
    }
}

trait Boo: Foo {
    fn method(&self) {
        // this is overriding the default implementation
        Foo::method(self);  // here, we successfully call the original
                            // this is tested to work properly
        println!("I am doing something more.");
    }
}

struct Bar;

impl Foo for Bar {
    fn method(&self) {
        // this is overriding the default implementation as well
        Foo::method(self);  // this apparently calls this overridden
                            // version, because it overflows the stack
        println!("Hey, I'm doing something entirely different!");
        println!("Actually, I never get to this point, 'cause I crash.");
    }
}

fn main() {
    let b = Bar;
    b.method();     // results in "thread '<main>' has overflowed its stack"
}

因此,在继承特征的情况下,调用原始默认实现是没有问题的,但是,在实现结构时使用相同的语法会表现出不同的行为。这是 Rust 中的问题吗?有办法解决吗?或者我只是错过了什么?

最佳答案

现在不能直接这样做。

然而,RFC 1210: impl specialization包含使这种行为起作用的各个方面,例如,像这样的东西应该起作用:

trait Foo {
    fn method(&self) { println!("default implementation"); }
}
trait Bar: Foo { ... }

partial impl<T: Bar> Foo for T {
    default fn method(&self) { println!("Bar default"); }
}

super调用被明确提到为 an extension因此不一定会立即出现,但可能会在未来出现。

同时,通常采用的做法是为默认行为定义一个单独的函数,并在默认方法中调用,然后用户可以模拟super::...。通过直接调用该函数来调用:

trait Foo {
    fn method(&self) { do_method(self) }
}

fn do_method<T: Foo>(_x: &T) {
    println!("default implementation");
}

impl Foo for Bar {
    fn method(&self) {
        do_method(self);
        println!("more");
    }
}

也就是说,Rust 更喜欢组合而不是继承:在 Java 中运行良好的设计不能也不应该一对一地强制到 Rust 中。

    Foo::method(self);  // this apparently calls this overridden
                        // version, because it overflows the stack

限定路径语法,Trait::method(value)是糖 <Type as Trait>::method(value)其中 Typevalue 的类型(或者,可能是取消引用多次后的类型)。也就是说,它正在调用您发现的特定类型的方法。

关于oop - 是否可以扩展结构中特征的默认方法实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31461902/

相关文章:

java - 是否有一个 java 方法的名称被认为与任何特定类分开?

c# - 强制 C# 方法只传递正参数?

c++ - 覆盖C++虚函数时的错误

java - 创建返回子类对象的父类

unit-testing - 如何编写 Rust 单元测试以确保发生 panic ?

php - 无法使用 __PHP_Incomplete_Class 类型的对象作为数组(与 session 相关?)

php - 重构困境 : User Account Functionality in PHP

c++ - c++ 中的高性能代码(继承、指向函数的指针、if)

vector - 在 Rust 中连接向量的最佳方法是什么?

Rust - 由于需求冲突,无法推断出 autoref 的适当生命周期