2017-05-19 5 views
1

あり、私が使用したいいくつかの最小限のサンプル・ライブラリーのコードは次のとおりです。これを解決するには "十分に長く生きていません"?

struct MyR<'a> { 
    x: &'a str, 
} 

struct T { 
    x: &'static str, 
} 

impl T { 
    fn bar<'a>(&'a self) -> MyR { 
     MyR { x: self.x } 
    } 
} 

次は私のコードです:

trait A<R, F: FnMut(&R)> { 
    fn foo(&mut self, callback: &mut F); 
} 

impl<'a, F> A<MyR<'a>, F> for T 
    where F: FnMut(&MyR<'a>) 
{ 
    fn foo(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); // t does not live long enough (for 'a) 
     callback(&r); 
     println!("abc"); 
    } 
} 

fn test() { 
    let mut t = T { x: "l" }; 
    let mut i = 1; 
    t.foo(&mut |x| { i += x.x.len(); }); 
} 

私はコールバックによってパラメータ化された形質をしたいと思いますが、私はそれを正しくするために苦労した。

impl T { 
    fn foo<F: FnMut(&MyR)>(&mut self, callback: &'a mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); 
     callback(&r); 
     println!("abc"); 
    } 
} 

しかし、私はこれを行うことはできません:私は形質を使用しない場合は、それがうまく機能

impl T { 
    fn foo<'a, F: FnMut(&MyR<'a>)>(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); 
     callback(&r); 
     println!("abc"); 
    } 
} 

私はこの問題は、t'aより長生きしなければならないということですけど、私は知りませんよりも寿命が短くなるように'aにバインドしてください。

私はrustc 1.19.0を毎晩使用しています。

答えて

1

エラーメッセージを読む:

  1. tは十分な長さ住んでいない - それはfoo関数の終わりまで住んでいます。
  2. 借り値が生涯「の有効である必要があります - あなたは'a指定されている:

    impl<'a, F> A<MyR<'a>, F> for T 
        where F: FnMut(&MyR<'a>) 
    

    これはすべての可能な寿命のために、形質は限り、実施されると述べていますFFnMut形質を実装しています。

その仕事をするだけ可能な方法があります - あなたは'static寿命でパラメータ化されMyRを持っている必要があります。それは、任意の生涯を生き延びることが保証されている唯一の生涯です。あなたが戻ってThe Rust Programming Language section on lifetime elisionを再読した場合、あなたはこの一生の仕様が値を提供しないことを認識します

fn bar<'a>(&'a self) -> MyR { 
    MyR { x: self.x } 
} 

MyRがどこから来るか見てみましょう。それは生涯を定義し、selfでそれを使用しますが、決して出力寿命には結びついていません。コードは同じです:

fn bar<'a, 'b>(&'a self) -> MyR<'b> 

あなたが一生を削除した場合、その後、あなたは

fn bar(&self) -> MyR 
fn bar<'a>(&'a self) -> MyR<'a> // equivalent 

を持っていると思いますが、これらのいずれも'static寿命です。幸いにも、あなたのために、あなたはちょうどあなたの署名で、コードがコンパイルされますことを反映することができますので、そのxは、&'static strであることを知っている:

fn bar(&self) -> MyR<'static> 
+0

私はlibにコードを変更することはできませんよ。私は自分のコードを変更することしかできません。 'fn foo (&mut self、コールバック:& 'a mut F)'という抽象的な特性を作り出す方法はありませんか? – colinfang

0

を様々なアプローチを試みて時間を過ごす、これは

trait A<F> { 
    fn foo(&mut self, callback: &mut F); 
} 

impl<F> A<F> for T 
    where F: FnMut(&MyR) 
{ 
    fn foo(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); // t does not live long enough (for 'a) 
     callback(&r); 
     println!("abc"); 
    } 
} 

fn main() { 
    let mut t = T { x: "l" }; 
    let mut i = 1; 
    t.foo(&mut |x: &MyR| { i += x.x.len(); }); 

} 
を動作するようです

主な違いは次のとおりです。

  • 私はそれが任意の型をとるようにビットを特色失うする必要があります。
  • 私がインプラントするとき、私は生涯を全く指定する必要はありません。
  • 関数を呼び出すときにクロージャに注釈を入力する必要があります。

Playground

関連する問題