抱歉我有一种“面向对象”的思维方式(在某种程度上),但我很难想象如何在Rust中创建以下类似物:
在Python中,我可以定义一个基类,并将其方法定义为抽象/未实现状态(raise NotImplementedException
)或具有默认实现。然后我可以创建一个mixin类以覆盖基类的行为。最后,我可以将基类和mixin类组合成一个子类,其中mixin方法是绑定到子类的方法。我可以完成所有这些操作,以尝试满足另一个代码片段的接口需求,该代码片段与这些对象进行交互。我想在Rust中完成这个过程,而又不使用需要C++ vtables等价物的动态运行时多态。在Python中,我会像以下示例代码一样处理愚蠢的接口do_it
:
class Base(ABC): @abstractmethod def do_it(self): pass
class Mixin: def do_it(self): print("Mixin here")
class Child(Base, Mixin): pass
c = Child() c.do_it() ```
def do_it(inst):
inst.must_implement_me()
class Base:
def must_implement_me(self):
print('base default implementation')
class Mixin:
def must_implement_me(self):
print('mixin override new default')
class ChildClass(Mixin, Base):
pass
do_it(Base()) # prints "base default implementation"
do_it(ChildClass()) # prints "mixin override new default"
当我在 Rust 中尝试达到相同的目标时:
trait DoIt {
fn must_implement_me(&self);
}
fn do_it<T: DoIt>(inst: T) {
inst.must_implement_me();
}
trait Base {}
impl<T> DoIt for T where T: Base {
fn must_implement_me(&self) {
println!("base default implementation");
}
}
trait Mixin {}
impl<T> DoIt for T where T: Mixin {
fn must_implement_me(&self) {
println!("mixin override new default");
}
}
struct BaseClass();
impl Base for BaseClass{}
struct ChildClass();
impl Base for ChildClass {}
impl Mixin for BaseClass {}
fn main() {
do_it(BaseClass());
do_it(ChildClass());
}
cargo run
提示错误:
error[E0119]: conflicting implementations of trait `DoIt`:
--> src/main.rs:20:1
|
13 | impl<T> DoIt for T where T: Base {
| -------------------------------- first implementation here
...
20 | impl<T> DoIt for T where T: Mixin + Base {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
有没有一种方法可以告诉Rust,让Mixin实现胜出?我知道这可能存在歧义,但是我能不能明确地告诉Rust哪个方法实现胜出?如果不行,还有什么其他方法可以实现这个目标吗?
Base
是Animal
,Mixin
是Dog
(或更可能是HasLegs
,代表"mixin"的想法),而ChildClass
是Dalmation
。Dalmation
获取了所有覆盖Animal
的Dog
方法,但不必实际实现Dog
方法。无论如何,我知道我的思维方式非常面向对象,但在某些情况下,这种模式是有成效的,所以我需要你们的帮助来翻译这个思维模型。 - Ross Rogers