2017-11-17 11 views
2

私はS1タイプで動作するalgoの機能を持っていますが、 タイプS2もあり、すべてのフィールドにS1といくつかの追加フィールドが含まれています。異なる位置にある同様のフィールドを持つ2つのタイプの関数を一般化するにはどうすればよいですか?

どのように私は がS2からタイプS1とデータとの一時変数を作成しなくても、入力としてS2を受け入れるようにalgoを変更する必要がありますか?私は

こだわっている

struct Moo1 { 
    f1: String, 
    f2: i32, 
} 

struct Moo2 { 
    f1: String, 
    f2: i32, 
    other_fields: f32, 
} 

struct S1 { 
    x: i32, 
    v: Vec<Moo1>, 
} 

struct S2 { 
    x: i32, 
    v: Vec<Moo2>, 
} 

//before fn algo(s: &S1) 
fn algo<???>(???) { 
    //work with x and v (only with f1 and f2) 
} 

のはalgoは(私の実際のアプリケーションは、別の実装を持っている)この実装を持っていると仮定しましょう:

fn algo(s: &S1) { 
    println!("s.x: {}", s.x); 
    for y in &s.v { 
     println!("{} {}", y.f1, y.f2); 
    } 
} 

Moo1Moo2のフィールドにアクセスするために私がご紹介trait AsMooxフィールドにアクセスし、vにアクセスするには、trait AsS

trait AsMoo { 
    fn f1(&self) -> &str; 
    fn f2(&self) -> i32; 
} 

trait AsS { 
    fn x(&self) -> i32; 
    // fn v(&self) -> ???; 
} 

fn algo<S: AsS>(s: &AsS) { 
    println!("s.x: {}", s.x()); 
} 

私はAsS::vメソッドの実装に固執しています。私はalgoを使用するためにメモリを割り当てませんが、何とかVec<&AsMoo>が必要です。

多分私はIterator<&AsMoo>の何らかの種類を返す必要がありますが、それを行う方法はわからず、この問題は複雑に見えます。

代わりにマクロを使用する必要がありますか?

+0

[Generics](https://doc.rust-lang.org/1.11.0/book/generics.html)を認識していますか?その目的は一般化することです! @MatthieuM。 –

+0

私は形質を必要とする分野にアクセスするのはそれほど単純ではありませんが、 'Vec'は既知のサイズが必要であり、ヒープベクターの特徴を割り当てることは望ましくありません。 – user1244932

+1

ああ!だからあなたは何かを試しました。この場合、使用しようとしている形質の定義を編集し、それに満足できないものを編集できますか?このようにして、あなたの望みに合うように改善することができます:) –

答えて

4

コンピュータサイエンスの問題は、間接指示の別の層を追加することで解決できます。もちろん、そのような層があまりにも多くあることを除いて。

したがって、S1S2を一般化するためにSの特性が欠けているということは間違いありません。 Sでは、あなたは関連するタイプと呼ばれる機能を使用することができます。

trait Moo { 
    fn f1(&self) -> &str; 
    fn f2(&self) -> i32; 
} 

trait S { 
    type Mooer: Moo; 
    fn x(&self) -> i32; 
    fn v(&self) -> &[Self::Mooer]; 
} 

ビットがtype Mooer: Moo;言う:私はかなり正確なタイプMooerがいることになりますかわからないが、それはMoo形質を実装します。

これは、あなたが書くことができます:

impl S for S1 { 
    type Mooer = Moo1; 
    fn x(&self) -> i32 { self.x } 
    fn v(&self) -> &[Self::Mooer] { &self.v } 
} 

impl S for S2 { 
    type Mooer = Moo2; 
    fn x(&self) -> i32 { self.x } 
    fn v(&self) -> &[Self::Mooer] { &self.v } 
} 

fn algo<T: S>(s: &T) { 
    println!("s.x: {}", s.x()); 
    for y in s.v() { 
     println!("{} {}", y.f1(), y.f2()); 
    } 
} 

そして、あなたの一般的なalgoはどんなタイプMooerがされて終わることを知っているMooのインタフェースが利用可能であるので、それはMoo形質に準拠しています。

関連する問題