如何通过“parent”上定义的构造函数获得类似继承的功能?

问题描述 投票:0回答:1

我尝试在 Rust 中使用类似 struct

SomeStruct<T>
的东西,它以通用方式完成大部分繁重的工作,并且还实现了通用构造函数,但是根据类型 T 有一些小的变化。在其他语言中,我会只需使用包含大部分代码的父类来实现它并从中继承子类型,例如在Python中:

from abc import ABC, abstractmethod

class SomeStruct(ABC):
    def __init__(self):
        self.some_value = 1

    @abstractmethod
    def foo(self):
        pass
        
    def bar(self):
        return self.some_value + self.foo()
    
class A(SomeStruct):
    def foo(self):
        return 1

class B(SomeStruct):
    def foo(self):
        return 2
    
class C(SomeStruct):
    def foo(self):
        return 3
    
if __name__ == '__main__':
    a = A()
    b = B()
    c = C()
    print(a.bar() + b.bar() + c.bar())

我在 Rust 中尝试的是使用空枚举作为子类型:

trait SomeType {
    fn new() -> SomeStruct<Self> where Self: Sized {
        SomeStruct {
            struct_type: Self,
            some_value: 1,
        }
    }

    fn foo(&self) -> i32;
}

struct SomeStruct<T> {
    struct_type: T,
    some_value: i32,
}

enum A {}
impl SomeType for A {
    fn foo(&self) -> i32 { 1 }
}

enum B {}
impl SomeType for B {
    fn foo(&self) -> i32 { 2 }
}

enum C {}
impl SomeType for C {
    fn foo(&self) -> i32 { 3 }
}

impl<T> SomeStruct<T> {
    fn bar(&self) -> i32 where T: SomeType {
        self.some_value + self.struct_type.foo()
    }
}

fn main() {
    let a = A::new();
    let b = B::new();
    let c = C::new();
    println!("{}", a.bar() + b.bar() + c.bar());
}

但是,这不会编译,因为不允许将类型分配给第 4 行中的变量,

struct_type: Self

有没有办法解决这个问题并获得类似的行为,而不需要为每个 A、B、C 重新实现构造函数?

我发现了这个相关问题,我想我可以为我的案例工作,用包含父结构 SomeStruct 的结构替换 A、B、C,但我很好奇是否还有一种方法可以使空枚举解决方案有效,或者如果我只是走在完全错误的轨道上?

inheritance rust
1个回答
0
投票

这是一种与问题中提出的方法相反的解决方案:

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

struct SomeStruct<T> {
    some_type_field: T,
    some_value: i32,
}

impl<T> SomeStruct<T> {
    fn new(t: T) -> SomeStruct<T> {
        SomeStruct {
            some_type_field: t,
            some_value: 1,
        }
    }
    
    fn bar(&self) -> i32 where T: SomeType {
        self.some_value + self.some_type_field.foo()
    }
}

struct A;
impl SomeType for A {
    fn foo(&self) -> i32 { 1 }
}

struct B;
impl SomeType for B {
    fn foo(&self) -> i32 { 2 }
}

struct C;
impl SomeType for C {
    fn foo(&self) -> i32 { 3 }
}

fn main() {
    let a = SomeStruct::new(A);
    let b = SomeStruct::new(B);
    let c = SomeStruct::new(C);
    println!("{}", a.bar() + b.bar() + c.bar());
}

逻辑的核心不是依赖于构造函数和继承,而是留在具体的

SomeStruct
类型中。 它利用组合来将公共逻辑包装在 A、B 和 C 的实例周围。

虽然这主要是个人喜好问题,但我通常不依赖 Rust 中的复杂构造函数或继承,因为我发现这些面向对象的模式不能很好地映射到该语言的哲学。

© www.soinside.com 2019 - 2024. All rights reserved.