我正在为Rust构建一个Raft一致性算法中间件,它具有与copycat类似的架构.我为开发人员编写了一个宏来定义命令方案.宏生成具有用户定义命令A的dispatch函数的特征,这需要开发人员为其行为实现结构,并且编码器/解码器与该主题无关.
特征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不会执行dispatch的B.当我实施的结构A,编译器仍然要求执行dispatch的B.
我也尝试将dispatch特性B转移到另一个特征作为父特征B,但特征无法实现A.
我还审查了https://github.com/rust-lang/rfcs/issues/1024.似乎问题是开放的,但已被抛弃.有没有其他方法可以使这种模式有效?
你根本不需要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)
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |