2016-04-09 15 views
1

get_idをパラメータとする関数aggを作成し、get_id関数を使用するFnMutクロージャを返します。クロージャ内で関数ポインタパラメータを使用するルチル

具体例:

エラーが発生し
struct CowRow { 
    pub id : i32, 
} 
impl CowRow { 
    fn get_id(&self) -> i32  { self.id } 
} 

pub fn agg<F>(col: F) -> Box<FnMut(&CowRow) -> i32> 
    where F: Fn(&CowRow) -> i32 { 
    let mut res = 0; 
    Box::new(move |r| { res += col(&r); return res }) 
} 

fn main() { 
    let mut cow = CowRow { id: 0 }; 
    let a = agg(CowRow::get_id); 
    a(&cow); 

the parameter type `F` may not live long enough [E0310] 

run `rustc --explain E0310` to see a detailed explanation 

consider adding an explicit lifetime bound `F: 'static`... 

...so that the type `[[email protected]:23:14: 23:53 col:F, res:i32]` will meet its required lifetime bounds 

ここでの考え方は、私が構造体の異なるフィールド上で動作クロージャを作成することができ、一般的な機能をしたいということです。だから、私の考えは構造体のゲッターである関数を渡し、クロージャーでこれを使って適切なフィールドを抽出することでした。

私はagg署名に'staticを加えるの様々な組み合わせを試してみたが、私はそれが実際に何を意味するのかわからないんだけど、どこでそれが構文的に移動する必要があります。さらに、私は、メソッドを特性として追加するなど、多くのテクニックを試しましたが、それを得ることはできませんでした。

答えて

4

関数への型パラメータFは、(他のすべての型と同様に)関連する存続時間を持ちます。しかし暗黙のうちに、関数の戻り値Box<FnMut(&CowRow) -> i32>は、実際にはBox<FnMut(&CowRow) -> i32 + 'static>です。つまり、ボックスの有効期間を指定しない限り、その内容は永遠に存続できるとみなされます。もちろん、F'aのためだけに生存している場合、借りチェッカーは不平を言うでしょう。それはボックス内に永遠に生きることができるように静的な寿命を持っているのいずれか

  • フォース、(playpen)をFをこの問題を解決するには、次の

    fn agg<F>(col: F) -> Box<FnMut(&CowRow) -> i32> 
        where F: Fn(&CowRow) -> i32 + 'static 
    { 
        ... 
    } 
    
  • は、明示的にFが寿命'aがあり、そうすることを述べますBoxplaypen):

    fn agg<'a, F>(col: F) -> Box<FnMut(&CowRow) -> i32 + 'a> 
        where F: Fn(&CowRow) -> i32 + 'a 
    { 
        ... 
    } 
    

2番目のバージョンは最初のバージョンよりも一般的で、より多くのクロージャを引数として受け入れます。

+0

完璧、ありがとう! – josh

関連する問題