在闭包Rust中使用函数指针参数

时间:2016-04-09 16:30:25

标签: closures rust function-pointers lifetime

我希望创建一个函数agg,它将另一个函数get_id作为参数,并返回使用FnMut的{​​{1}}闭包。功能

具体例子:

get_id

产生错误:

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);

这里的想法是我想要一个泛型函数,它允许创建在结构中不同字段上运行的闭包。所以,我的想法是传递一个函数,它是结构的getter,并在闭包中使用它来提取适当的字段。

我尝试过将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 `[closure@main.rs:23:14: 23:53 col:F, res:i32]` will meet its required lifetime bounds 添加到'static签名的各种组合,但我不确定这实际意味着什么以及它需要在语法上去哪里。此外,我尝试了以下几种技术:https://github.com/nrc/r4cppp/blob/master/closures.md,例如将agg方法添加为特征但无法使其正常工作。

1 个答案:

答案 0 :(得分:5)

函数的类型参数F具有关联的生命周期(就像所有其他类型一样)。但隐含地,函数Box<FnMut(&CowRow) -> i32>的返回值实际上是Box<FnMut(&CowRow) -> i32 + 'static>。也就是说,除非您为框指定生命周期,否则它会假定其内容可以永久存在。当然如果F只适用于'a,那么借阅检查员会抱怨。要解决这个问题,

  • 强制F拥有静态生命周期,以便它可以永久存在于框内(playpen):

    fn agg<F>(col: F) -> Box<FnMut(&CowRow) -> i32>
        where F: Fn(&CowRow) -> i32 + 'static
    {
        ...
    }
    
  • 明确声明F有生命周期'aBoxplaypen)也是如此:

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

第二个版本比第一个版本更通用,并且将接受更多闭包作为参数。