为什么我不能 return 来自闭包的引用?
Why can I not return a reference from a closure?
fn main() {
let _ref_in_ref_out = |var: &i64| var;
}
这不编译:
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`
显然,编译器推断出两个不同的生命周期(对于参数和 return 类型),而不是相同。
是否可以编写一个闭包,使输入生命周期与输出生命周期相同?
类似
fn ref_in_ref_out<'a> (var: &'a i64) -> &'a i64 { var }
但作为一个闭包
我刚刚找到了解决这个问题的方法,但如果有更简单的解决方案就更好了:
fn infer_lifetime<'a, T: 'a, F: Fn(&'a T) -> &'a T>(f: F) -> F {
f
}
fn main() {
let _ref_in_ref_out = infer_lifetime(|var: &i64| var);
}
生命周期省略规则 do not apply to closures,您也不能明确指定闭包的生命周期。不过,有几种方法可以使此代码正常工作。
最简单的解决方案是简单地省略类型注释并让编译器推断一切:
let ref_in_ref_out = |var| var;
let i: i64 = 42;
ref_in_ref_out(&i);
或者,指定 return 类型实际上很好。这编译:
let _ref_in_ref_out = |var| -> &i64 { var };
对于闭包不关闭任何局部变量的情况,另一种选择是将其转换为函数指针,因为生命周期省略规则适用于函数指针:
let ref_in_ref_out: fn(&i64) -> &i64 = |var| var;
最后,最通用的解决方案是使用辅助函数来应用绑定到闭包的函数特征:
fn constrain_closure<F: Fn(&i64) -> &i64>(f: F) -> F {
f
}
let _ref_in_ref_out = constrain_closure(|var| var);
fn main() {
let _ref_in_ref_out = |var: &i64| var;
}
这不编译:
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`
显然,编译器推断出两个不同的生命周期(对于参数和 return 类型),而不是相同。
是否可以编写一个闭包,使输入生命周期与输出生命周期相同?
类似
fn ref_in_ref_out<'a> (var: &'a i64) -> &'a i64 { var }
但作为一个闭包
我刚刚找到了解决这个问题的方法,但如果有更简单的解决方案就更好了:
fn infer_lifetime<'a, T: 'a, F: Fn(&'a T) -> &'a T>(f: F) -> F {
f
}
fn main() {
let _ref_in_ref_out = infer_lifetime(|var: &i64| var);
}
生命周期省略规则 do not apply to closures,您也不能明确指定闭包的生命周期。不过,有几种方法可以使此代码正常工作。
最简单的解决方案是简单地省略类型注释并让编译器推断一切:
let ref_in_ref_out = |var| var;
let i: i64 = 42;
ref_in_ref_out(&i);
或者,指定 return 类型实际上很好。这编译:
let _ref_in_ref_out = |var| -> &i64 { var };
对于闭包不关闭任何局部变量的情况,另一种选择是将其转换为函数指针,因为生命周期省略规则适用于函数指针:
let ref_in_ref_out: fn(&i64) -> &i64 = |var| var;
最后,最通用的解决方案是使用辅助函数来应用绑定到闭包的函数特征:
fn constrain_closure<F: Fn(&i64) -> &i64>(f: F) -> F {
f
}
let _ref_in_ref_out = constrain_closure(|var| var);