在这种情况下(Vec<&Fn(i32) -> i32>),借用值的生命周期不够长。

3

我遇到了这个错误,以前有类似的问题并且已经以不同的方式解决了,但是现在无法解决这个问题:

借用的值在此处并未存活足够长

我将代码移动到更简单的位置,但是我找不到错误所在:

fn main(){

    let mut v: Vec<&Fn(i32) -> i32> = Vec::new();

    v.push(&ops_code1);
    //v.push(&ops_code2);
    //v.push(&ops_code3);
}

fn ops_code1(value: i32) -> i32 {
..//

错误:借用的值没有足够长的生命周期

v.push(&ops_code1);

play.rust


你能在 https://play.rust-lang.org/ 分享整个文件吗? - Cengiz Can
@CengizCan 确实看起来很升级。 - Angel Angel
1个回答

3
你在这里做的是创建一个闭包的Vec。在Rust中,静态函数与闭包略有不同,因此当我们创建引用时,实际上会创建一个闭包。如果我们在创建Vec之后再创建引用,则生成的闭包的寿命比Vec短,这是错误的。相反,我们可以使用let在创建Vec之前创建闭包,从而给出足够长的寿命,使其超出Vec的生命周期。
fn main() {
    let extended = &ops_code1;

    let mut v: Vec<&Fn(i32) -> i32> = Vec::new();

    // Note that placing it here does not work:
    // let extended = &ops_code1;

    v.push(extended);
    //v.push(&ops_code2);
    //v.push(&ops_code3);

}

fn ops_code1(value: i32) -> i32 {
    println!("ops_code1 {}", value);
    value
}

Rust Playground

然而,如果您只使用静态函数-而不是闭包-则以下内容也可以正常工作,并且让您避免额外的let:

fn main() {
    let mut v: Vec<fn(i32) -> i32> = Vec::new();

    v.push(ops_code1);
    v.push(ops_code2);
}

fn ops_code1(value: i32) -> i32 {
    println!("ops_code1 {}", value);
    value
}

fn ops_code2(value: i32) -> i32 {
    println!("ops_code2 {}", value);
    value
}

Rust Playground

第三个选项是使用boxed closures,它让你可以同时使用闭包和静态函数,而不需要额外的let语句,但是也有其自己的权衡。

fn main() {
    let mut v: Vec<Box<Fn(i32) -> i32>> = Vec::new();

    v.push(Box::new(ops_code1));
    v.push(Box::new(ops_code2));

    for f in v {
      f(1);
    }
}

fn ops_code1(value: i32) -> i32 {
    println!("ops_code1 {}", value);
    value
}

fn ops_code2(value: i32) -> i32 {
    println!("ops_code2 {}", value);
    value
}

Rust 操场


谢谢,这真的很有用。但我有一个问题,我需要创建与函数数量相同的 let extended = &ops_codeX; 吗?还有其他方法可以做到这一点而无需创建 let 吗?编辑:我是 Rust 的新手,但我认为您的更新是我所使用的,感谢您的时间。 - Angel Angel
1
let关键字本质上是将静态函数用作闭包。因此,每个静态函数(对于第一种替代方案)只需要使用一次。我在这个主题上进行了更多的阅读,我会扩展我的答案以进一步解释。 - Erik Vesteraas
谢谢提供详细信息,但很抱歉我无法再投更多的票。 - Angel Angel
当然,没问题。只是想在更深入理解问题的基础上改进我的答案。 :) - Erik Vesteraas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接