2016-12-03 65 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

相關問題