2016-12-03 11 views
0

私は、copycatと同様のアーキテクチャを持つRustのためのRaftコンセンサスアルゴリズムミドルウェアを構築しています。開発者がコマンドのスキームを定義するためのマクロを書きました。このマクロは、ユーザー定義のコマンドに対してdispatchという機能を持つ特性Aを生成します。これは、開発者がその動作のために構造体を実装し、このトピックとは関係のないエンコーダ/デコーダを必要とするためです。形質の親形質を実現するための代替手段はありますか?

特性オブジェクトは、Serverオブジェクトを登録して機能させます。形質Aが動的に生成されるので、Aの親形質として別の形質Bを定義する必要があります。 Serverは、Bと連携して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機能はBdispatchを実装していません。 Aの構造体を実装すると、コンパイラはまだBのためにdispatchを実装するよう依頼しました。

私もBの親形質として他の形質に特色Bdispatchを移動しようとしたが、トレイトはAのために実装することはできません。

https://github.com/rust-lang/rfcs/issues/1024も確認しました。問題は開いているようだが、捨てられているようだ。このパターンを動作させる代替方法はありますか?

+0

あなたの質問は非常に明確ではありません。なぜ、 'A'特性を作り出すマクロを展開すると同時に' B'を実装しないのですか? – Shepmaster

+0

@Shepmasterマクロによって生成されたAのようなより多くの形質が存在するため、サーバーはディスパッチを呼び出すために共通の特性を必要とします。 – 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

ありがとうございます。しかし、 '' f'のような 'B'に別の関数があるとすれば、' 'S''の開発者が実装すべき質問に更新がありますか? – Shisoft

+0

開発者が 'A'に' foo'を追加し、生成された 'B' impl呼び出しをそれにしますか? –

+0

この場合、 'B'を探しているサーバーはそれを見ることができません – Shisoft