特质实现其父特质的任何替代方式?

Shi*_*oft 0 traits rust

我正在为Rust构建一个Raft一致性算法中间件,它具有与copycat类似的架构.我为开发人员编写了一个宏来定义命令方案.宏生成具有用户定义命令Adispatch函数的特征,这需要开发人员为其行为实现结构,并且编码器/解码器与该主题无关.

特征Server对象向对象注册以使其工作.因为trait A是动态生成的,所以我必须将另一个特征定义B为父特征A.Server作品有B调用dispatch中定义的函数A.

我尝试了不同的组合,但没有一个有效.

trait B {
    fn dispatch(&mut self, fn_id: u64) -> Vec<u8>;
}

// macro generated trait
trait A: B {
    fn a(&self) -> Vec<u8>;
    fn b(&self) -> Vec<u8>;
    fn dispatch(&mut self, fn_id: u64) -> Vec<u8> {
        match fn_id {
            1 => a(),
            2 => b(),
            _ => {}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,dispatch在功能上A不会执行dispatchB.当我实施的结构A,编译器仍然要求执行dispatchB.

我也尝试将dispatch特性B转移到另一个特征作为父特征B,但特征无法实现A.

我还审查了https://github.com/rust-lang/rfcs/issues/1024.似乎问题是开放的,但已被抛弃.有没有其他方法可以使这种模式有效?

Chr*_*son 6

你根本不需要B成为一个超级的人A.您可以B为任何添加毯子实现T: A.我认为这更接近意图.

解释Rust代码:

trait A: B {
Run Code Online (Sandbox Code Playgroud)

"你可以实施A,但前提是你已经实施了B."

trait A {
    //...
}
impl<T: A> B for T {
Run Code Online (Sandbox Code Playgroud)

"如果你实施A,这里是一个免费的实现B."

这是完整版:

trait B {
    fn dispatch(&mut self, fn_id: u64) -> Vec<u8>;
}

// macro generated trait
trait A {
    fn a(&self) -> Vec<u8>;  // added &self
    fn b(&self) -> Vec<u8>;
}

impl<T: A> B for T {
    fn dispatch(&mut self, fn_id: u64) -> Vec<u8> {
        match fn_id {
            1 => self.a(),
            2 => self.b(),
            _ => panic!(),   // Needed so that match cases are exhaustive
        }
    }
}

struct S {}

impl A for S {
    fn a(&self) -> Vec<u8> {
        unimplemented!()
    }
    fn b(&self) -> Vec<u8> {
        unimplemented!()
    }
}
Run Code Online (Sandbox Code Playgroud)

操场