2016-07-12 10 views
2

に拘束されているにもかかわらず、十分な長さ住んでいない:値は、次の錆のコードはコンパイルに失敗し

pub struct UserAction<'u> { 
    _act: &'u mut (FnMut() + 'u) 
} 

impl<'u, F: FnMut() + 'u> From<F> for UserAction<'u> { 
    fn from(f: F) -> Self { 
     UserAction { _act: (&mut f) as &'u mut (FnMut() + 'u) } 
    } 
} 

私はrustc 1.10 stableから取得するエラーは次のとおりです。

lives.rs:7:38: 7:39 error: `f` does not live long enough 
lives.rs:7    UserAction { _act: (&mut f) as &'u mut (FnMut() + 'u) } 
               ^
lives.rs:6:31: 8:10 note: reference must be valid for the lifetime 'u as defined on the block at 6:30... 
lives.rs:6   fn from(f: F) -> Self { 
             ^
lives.rs:6:31: 8:10 note: ...but borrowed value is only valid for the scope of function body at 6:30 
lives.rs:6   fn from(f: F) -> Self { 
             ^
error: aborting due to previous error 

私はなぜこれがエラーであるのか分からない。タイプFは少なくとも生涯の長さが'uであり、それは制約されています。何が欠けていますか?このエラーを解決するにはどうすればよいですか?

答えて

3

mcarton saysとして、あなたはそれへの参照を取るしようとすると、関数にクロージャの所有権を渡しています。コンパイラが間違いを犯したことを喜んで、メモリ破損の原因となる範囲外の変数への参照を使用できないようにしてください。

制限F: FnMut() + 'uFFnMut形質を実装し、は寿命'uより長生き参照を含む型でなければならないと述べています。それは、F自体がその生涯を生き延びなければならないとは言いません。実際には、メソッドが終了した後にfに所有者がないことがわかります。したがって、その寿命は終了します。つまり、エラーです。

動作するはず最も直接的等価ではなく、形質オブジェクト参照箱入り形質オブジェクトを使用することである。

pub struct UserAction<F> { 
    _act: F, 
} 

impl<F: FnMut()> From<F> for UserAction<F> { 
    fn from(f: F) -> Self { 
     UserAction { _act: f } 
    } 
} 
:別の代替は、ジェネリック型を浸透する

pub struct UserAction<'u> { 
    _act: Box<FnMut() + 'u>, 
} 

impl<'u, F: FnMut() + 'u> From<F> for UserAction<'u> { 
    fn from(f: F) -> Self { 
     UserAction { _act: Box::new(f) } 
    } 
} 

+0

ありがとう!私は 'Box'ベースのアプローチで終わりました。 –

2

fは、fromメソッドのローカルなので、すべての参照です。 何が欲しいのです:

pub struct UserAction<'u> { 
    _act: &'u mut (FnMut() + 'u) 
} 

impl<'u, F: FnMut() + 'u> From<&'u mut F> for UserAction<'u> { 
//        ^^^^^^^ 
    fn from(f: &'u mut F) -> Self { 
//    ^^^^^^^ 
     UserAction { _act: f as &'u mut (FnMut() + 'u) } 
    } 
} 
+0

これがコンパイルされている間は、今は使用できません。 'Self :: from(&mut || {})'という表現は、「借りた値が十分に長く生きていない」というエラーを引き起こします。 –

+2

@ Ptharien'sFlameもしあなたが 'Self :: from'の結果より長く続く変数にクロージャーを置くと、それは参照が有効な長さで十分に有効になります。 – Shepmaster

関連する問題