首页 > 解决方案 > Rust:如何为特征的某些“子类”定义常见行为?

问题描述

在这种模式下,抽象类的某些功能由其抽象子类提供,如下所示(TypeScript):

abstract class Foo{  // could also be an interface
    abstract foo(): number;
}

abstract class FooFromBar{
    foo() { return this.bar() + 1; }
    abstract bar(): number;
}

class Data1 extends FooFromBar{
    bar() { return 5; }
}

alert(new Data1().foo());  // 6

现在我可以拥有更多FooFromBar使用该foo=bar+1功能的扩展类,以及更多Foo直接提供自定义扩展的类foo

现在我想在 Rust 中也一样。我的直觉是抽象类变成了特征,而具体类变成了实现它们的结构——但这可能是错误的,我对 Rust 很陌生。问题是我不知道如何为foo实现类型自动实现FooFromBar。我得到的最好的是:

trait Foo{
    fn foo(&self)->i32;
}

trait FooFromBar:Foo{
    fn bar(&self)->i32;
}
impl<S:FooFromBar> Foo for S{
    fn foo(&self)->i32{self.bar()+1}
}

struct DataBar;
impl FooFromBar for DataBar{
    fn bar(&self)->i32{5}
}

fn main() {
    println!("{}",DataBar.foo());  // 6
}

它有效,但这种方法存在严重问题。如果我添加另一个“子特征”,例如这样FooFromBaz实现foo=baz+2

trait FooFromBaz:Foo{
    fn baz(&self)->i32;
}
impl<S:FooFromBaz> Foo for S{
    fn foo(&self)->i32{self.baz()+2}
}

然后我收到一个错误,说明存在冲突的实现:

error[E0119]: conflicting implementations of trait `Foo`:
  --> src/main.rs:19:1
   |
8  | impl<S:FooFromBar> Foo for S{
   | ---------------------------- first implementation here
...
19 | impl<S:FooFromBaz> Foo for S{
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

FooFromBar在我看来,只有当有人真正创建了一个实现两者的类型时,它们才会发生冲突FooFromBaz——这真的意味着他们做了一件不合理的事情。但相反,即使没有任何结构实现它们,它也会失败。

所以问题是如何正确获得类似的行为?是否有一些更好的泛型魔法来获得它,或者它只是应该在 Rust 中完全不同地解决,问题只是我一直在思考类?

标签: inheritancerustabstract-classtraits

解决方案


推荐阅读