特征实现其父特征的任何替代方法?
Any alternative way for trait to implement its parent trait?
我正在为 Rust 构建一个 Raft 共识算法中间件,其架构与 copycat 相似。我为开发人员编写了一个宏来定义命令方案。宏为用户定义的命令生成一个特征 A
和一个 dispatch
函数,这需要开发人员为其行为实现一个结构和一个与本主题无关的 encoder/decoder。
特征对象向 Server
对象注册以使其工作。因为特征 A
是动态生成的,所以我必须定义另一个特征 B
作为 A
的父特征。 Server
与 B
一起调用在 A
.
中定义的 dispatch
函数
我尝试了不同的组合,但其中 none 个有效。
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(),
_ => {}
}
}
}
不幸的是,A
中的 dispatch
函数不会在 B
中实现 dispatch
。当我为 A
实现结构时,编译器仍然要求为 B
实现 dispatch
。
我还尝试将特征 B
中的 dispatch
移动到另一个特征作为 B
的父特征,但该特征无法实现 A
.
我也评论了https://github.com/rust-lang/rfcs/issues/1024。似乎这个问题是开放的,但已被抛弃。有没有其他方法可以使这种模式起作用?
你根本不需要 B
成为 A
的超级特质。您可以为任何 T: A
添加 B
的全面实施。我认为这更接近意图。
解释 Rust 代码:
trait A: B {
"You can implement A
, but only if you've implemented B
."
trait A {
//...
}
impl<T: A> B for T {
"If you implement A
, here's a free implementation of 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!()
}
}
我正在为 Rust 构建一个 Raft 共识算法中间件,其架构与 copycat 相似。我为开发人员编写了一个宏来定义命令方案。宏为用户定义的命令生成一个特征 A
和一个 dispatch
函数,这需要开发人员为其行为实现一个结构和一个与本主题无关的 encoder/decoder。
特征对象向 Server
对象注册以使其工作。因为特征 A
是动态生成的,所以我必须定义另一个特征 B
作为 A
的父特征。 Server
与 B
一起调用在 A
.
dispatch
函数
我尝试了不同的组合,但其中 none 个有效。
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(),
_ => {}
}
}
}
不幸的是,A
中的 dispatch
函数不会在 B
中实现 dispatch
。当我为 A
实现结构时,编译器仍然要求为 B
实现 dispatch
。
我还尝试将特征 B
中的 dispatch
移动到另一个特征作为 B
的父特征,但该特征无法实现 A
.
我也评论了https://github.com/rust-lang/rfcs/issues/1024。似乎这个问题是开放的,但已被抛弃。有没有其他方法可以使这种模式起作用?
你根本不需要 B
成为 A
的超级特质。您可以为任何 T: A
添加 B
的全面实施。我认为这更接近意图。
解释 Rust 代码:
trait A: B {
"You can implement A
, but only if you've implemented B
."
trait A {
//...
}
impl<T: A> B for T {
"If you implement A
, here's a free implementation of 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!()
}
}