2016-12-03 68 views
0

我正在构建一个类似于copycat的体系结构的Rust的Raft共识算法中间件。我为开发人员编写了一个宏来定义命令方案。该宏为用户定义的命令生成dispatch函数的特性A,这需要开发人员为其行为实现结构以及与此主题无关​​的编码器/解码器。特质实现其父特征的任何替代方法?

特征对象注册一个Server对象使其工作。因为特征A是动态生成的,所以我必须定义另一个特征B作为A的父特征。 ServerB一起使用来调用A中定义的dispatch函数。

我尝试了不同的组合,但没有一个可以工作。

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(), 
      _ => {} 
     } 
    } 
} 

不幸的是,在Adispatch功能不能B实现dispatch。当我实现A的结构时,编译器仍然要求为B实施dispatch

我也试图在特质B移动dispatch另一个特点为母体的特质对B,但性状不能实施A。我也回顾了https://github.com/rust-lang/rfcs/issues/1024。这个问题似乎是开放的,但已被放弃。有没有其他方法可以使这种模式起作用?

+0

你的问题不是很清楚。为什么不在实现'B'的同时扩展创建特征'A'的宏呢? – Shepmaster

+0

@Shepmaster,因为会有更多像宏生成的特征,服务器需要一个共同的特性来调用调度 – Shisoft

回答

5

根本不需要B是超级A。您可以为任何T: A添加B的一揽子实现。我认为这更接近意图。

复述锈代码:

trait A: B { 

“您可以实现A,但前提是你已经实现B。”

trait A { 
    //... 
} 
impl<T: A> B for T { 

“如果实现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!() 
    } 
} 

Playground

+0

谢谢你的答复。但是,如果在'B'中有另一个函数像'foo'那样,我应该在开发人员为'S'实现的问题中更新了吗? – Shisoft

+0

将'foo'添加到'A'以供开发者实现,并生成'B' impl调用? –

+0

在这种情况下,寻找'B'的服务器看不到它 – Shisoft

相关问题