我有一个特征A,它包含很多方法,同时我有很多结构体需要实现它,但我真的不想为结构体一一实现A,因为它有很多方法,而且有很多结构体。有很多重复的代码,看起来很糟糕!我的解决方案是我只是为 BaseA 实现 A 。 BaseA 实现了 Trait A 的所有方法,而 struct-B、struct-C、struct-D……只需根据需要实现 Trait A 的部分方法,剩下的就交给 BaseA 来做吧!
代码示例如下
trait A {
fn method1(&self);
fn method2(&self);
// untill method100(&self)!!!
}
struct BaseA {}
impl A for BaseA {
fn method1(&self) {
println!("i am BaseA 1");
}
fn method2(&self) {
println!("i am BaseA 2");
}
// untill method100(&self)!!!
}
struct B {
base: BaseA,
}
struct C {
base: BaseA,
}
struct D {
base: BaseA,
}
impl A for C {
fn method1(&self) {
println!("i am C 1");
}
fn method2(&self) {
self.baseA.method2();
}
// untill method100(&self)!!!
}
这个方案是通过委托给BaseA来实现的,避免了大量的重复代码,但是也很糟糕!我仍然需要为我的所有结构实现 method1 到 method100!
其实我以前都是用Java编码的,Java可以通过继承机制解决这个问题,那么对于我的Rust问题有什么更好的解决方案???
一种方法是让所有子结构实现
AsRef<BaseA>
并在委托给 BaseA
的特征定义中添加默认实现:
trait A: AsRef<BaseA> {
fn method1 (&self) {
self.as_ref().method1();
}
fn method2 (&self) {
self.as_ref().method1();
}
}
struct BaseA {}
impl AsRef<BaseA> for BaseA {
fn as_ref (&self) -> &BaseA {
&self
}
}
impl A for BaseA {
fn method1 (&self) {
println!("BaseA::method1");
}
fn method2 (&self) {
println!("BaseA::method2");
}
}
struct B {
base: BaseA,
}
impl AsRef<BaseA> for B {
fn as_ref (&self) -> &BaseA {
&self.base
}
}
impl A for B {
fn method1 (&self) {
println!("B::method1");
}
// No `method2` -> use the one from `BaseA`
}
fn main() {
let v = B { base: BaseA{} };
v.method1();
v.method2();
}
话虽如此,Rust 不是一种面向对象语言,从长远来看,尝试在 Rust 中强制使用面向对象模式将是痛苦的。相反,您应该尝试用 Rust 术语重新思考您的架构。