为什么我不能从闭包中返回引用?

jm4*_*ier 5 closures lifetime rust

fn main() {
    let _ref_in_ref_out = |var: &i64| var;
}
Run Code Online (Sandbox Code Playgroud)

这不编译:

error: lifetime may not live long enough
 --> src/main.rs:2:39
  |
2 |     let _ref_in_ref_out = |var: &i64| var;
  |                                 -   - ^^^ returning this value requires that `'1` must outlive `'2`
  |                                 |   |
  |                                 |   return type of closure is &'2 i64
  |                                 let's call the lifetime of this reference `'1`
Run Code Online (Sandbox Code Playgroud)

显然,编译器推断出两个不同的生命周期(对于参数和返回类型),而不是相同。

是否可以编写一个闭包,使输入生命周期与输出生命周期相同?

就像是

error: lifetime may not live long enough
 --> src/main.rs:2:39
  |
2 |     let _ref_in_ref_out = |var: &i64| var;
  |                                 -   - ^^^ returning this value requires that `'1` must outlive `'2`
  |                                 |   |
  |                                 |   return type of closure is &'2 i64
  |                                 let's call the lifetime of this reference `'1`
Run Code Online (Sandbox Code Playgroud)

但作为一个闭包

Sve*_*ach 9

生命周期省略规则不适用于闭包,您也不能明确指定闭包的生命周期。不过,有几种方法可以使此代码工作。

最简单的解决方案是简单地省略类型注释并让编译器推断所有内容:

let ref_in_ref_out = |var| var;
let i: i64 = 42;
ref_in_ref_out(&i);
Run Code Online (Sandbox Code Playgroud)

或者,指定返回类型实际上很好。这编译:

let _ref_in_ref_out = |var| -> &i64 { var };
Run Code Online (Sandbox Code Playgroud)

对于您的闭包不关闭任何局部变量的情况的另一种选择是将其转换为函数指针,因为生命周期省略规则适用于函数指针:

let ref_in_ref_out: fn(&i64) -> &i64 = |var| var;
Run Code Online (Sandbox Code Playgroud)

最后,最通用的解决方案是使用辅助函数来应用绑定到闭包的函数特征:

fn constrain_closure<F: Fn(&i64) -> &i64>(f: F) -> F {
    f
}

let _ref_in_ref_out = constrain_closure(|var| var);
Run Code Online (Sandbox Code Playgroud)