2016-06-28 5 views
0

私は形質Fooと構造Barを持っています。 Barは、を実装する任意の参照を保持するVecフィールドを持ちます。`self`をコレクションに変更可能な形質参照として追加するメソッドを書く方法は?

trait Foo { } 

struct Bar<'a> { 
    handlers: Vec<&'a mut Foo>, 
} 

私はFooを実装して、別の構造体Stuを持っている、とbarに自分自身を追加する方法addを持っています。

struct Stu { } 

impl Foo for Stu { } 

impl Stu { 
    fn add(&mut self, bar: &mut Bar) { 
     bar.handlers.push(&mut self); 
    } 
} 

Fooを実装し、add方法に仕上がっ行動が多様であり、私は(ここBarである)、それらのすべてを保持している構造体を必要とする構造体の多くの種類がありますので、私は上記のコードを書きました。しかし、コンパイラは文句:

&mut Stu: Fooをバインド形質が満たされていない

は、どのように私はこの問題を解決するか、自分の所望の最終目標を実現することができますか?

答えて

4

より慎重に誤差法を読む

&mut Stu: Fooをバインド形質が対

満たされていない:

impl Foo for Stu { } 

&mut StuではなくStuFooを実装しました。

Rustでは、値、不変参照および可変参照は3つの異なるエンティティであり、いずれかの特性を個別に実装できます。


2番目のコーナーケースは、&mut selfがパターンマッチングではないということです。規則的なパターンマッチングでは、&mut a: &mut Aは、aがタイプAであり、実際に他のパラメータが処理されることを意味します。

しかし、紛らわしい、&mut selfは、だからここselfのタイプは&mut Stuであるので、あなたがpushコールでさらにそれを修飾するべきではありません...

self: &mut Selfのためだけの構文糖です。


したがって、あなたがあなたのコードを修正する必要があります。この時点で

impl Stu { 
    fn add(&mut self, bar: &mut Bar) { 
     bar.handlers.push(self); 
    } 
} 

、あなたは一生の制約に関するエラーが発生します。selfBarよりも長生きすることをここに保証するものではありません。あなたはそれを動作させるために(同じ寿命を使用)、それに注釈を付ける必要があります。

impl Stu { 
    fn add<'a>(&'a mut self, bar: &mut Bar<'a>) { 
     bar.handlers.push(self); 
    } 
} 

注:寿命に注釈を付けるとき、それらすべてに注釈を付ける必要はあり;拘束したいものの名前を挿入するだけです。

1

コンパイルに成功した明示的な有効期間<'a, 'b>を含むようにプログラムを修正しました。

trait Foo { } 

struct Bar<'a> { 
    pub handlers: Vec<&'a mut Foo>, 
} 

struct Stu; 

impl Foo for Stu { } 

impl Stu { 
    fn add<'a,'b> (&'a mut self, bar: &'b mut Bar<'a>) { 
     bar.handlers.push(self); 
    } 
} 
fn main(){ 
    println!("{:?}", "success"); 
} 
関連する問題