普通函数和定义为闭包的函数之间的生命周期推断似乎存在差异。考虑以下最小示例:
fn foo(f: &String) -> &str {
f
}
fn bar() {
|f: &String| -> &str { f };
}
编译器(Rustc 1.69.0 with --edition=2021
)接受foo
,但拒绝bar
中的闭包(与foo相同的函数),并返回错误
error: lifetime may not live long enough
--> clos.rs:8:33
|
8 | move |f: &String| -> &str { f };
| - - ^ returning this value requires that `'1` must outlive `'2`
| | |
| | let's call the lifetime of this reference `'2`
| let's call the lifetime of this reference `'1`
在foo
的例子中,我的理解是编译器将其去糖为
fn foo<'a>(f: &'a String) -> &'a str { ... }
为什么它不对闭包做同样的事情呢?有没有什么方法可以自己手动指定生存期(特别是,我应该把<'a>
放在哪里来声明生存期)?
1条答案
按热度按时间yrdbyhpb1#
我认为这是因为对于函数来说,从来没有任何捕获的状态,因此输入和输出的生存期几乎总是连接的。对于封闭件,寿命可以来自环境。
您可以创建一个生成闭包的函数,它允许您使用
impl Fn
语法,这似乎可以正确地推断生存期,至少在本例中是这样。如果捕获任何状态,则需要将其作为参数传递给生成器函数。如果在某种情况下它不起作用,您可以使用
for
语法显式地指定生存期。有一个每晚的功能:
closure_lifetime_binder
。稳定后,它将允许您将for
注解添加到闭包表达式中,而不仅仅是traits。