Rust文档的closures部分有这个例子:
fn call_with_ref<'a, F>(some_closure: F) -> i32
where F: Fn(&'a i32) -> i32
{
let value = 0;
some_closure(&value)
}
这不会编译,因为正如文档所说:
当函数具有显式生存期参数时,该生命周期必须 至少与整个函数调用一样长。借钱 检查员会抱怨价值不够长,因为它 仅在函数体内声明后才在范围内。
错误消息
error: `value` does not live long enough
--> <anon>:5:19
|
5 | some_closure(&value);
| ^^^^^ does not live long enough
...
8 | }
| - borrowed value only lives until here
我无法理解这一点。这个价值不足够长的意义是什么意思?从我理解的价值生活到整个函数的调用。那么,&#34;生活在哪里不够长&#34;来自?
答案 0 :(得分:2)
当参数列表中出现生命周期时,这意味着调用者可以决定。它所选择的生命周期可以是它所喜欢的,甚至可能比关闭的寿命更长,甚至'static
。
以下是此错误阻止的错误示例:
fn call_with_ref<'a, F>(some_closure: F) -> i32
where F: FnMut(&'a i32) -> i32
{
let value = 0;
some_closure(&value)
}
fn main() {
let mut refstore: Option<&'static i32> = None;
call_with_ref(|r| {
refstore = Some(r);
*r
});
}
如果允许这个版本的call_with_ref
进行编译,它将允许在变量中存储对本地value
变量的悬空引用,该变量的存在时间更长。
注意我已将函数更改为FnMut
闭包以简化操作;使用Fn
和RefCell
可能会产生同样的不安全感,但这会使示例变得更加复杂。
(Playground with "bad" line commented out)
本书的closures section会显示for<'a>
语法,它会更改生命周期界限的含义。
翻译成英文,以下内容:
fn call_with_ref<'a, F>(some_closure: F) -> i32
where F: Fn(&'a i32) -> i32
表示大致&#34;给定生命周期'a
,以及一个可调用,其中引用了对i32
有效的'a
,我将返回{ {1}}&#34 ;.这意味着生命周期由i32
的调用者设置并且已修复。
相反,以下内容:
call_with_ref
表示&#34;给定一个可以引用任何生命的fn call_with_ref<F>(some_closure: F) -> i32
where F: for<'a> Fn(&'a i32) -> i32
的可调用者,我将返回i32
&#34;。不同之处在于闭包将接受任何引用生命周期(它比闭包的调用更长)。
在第一种情况下,生命周期是i32
的参数,因此必须比该调用更长;但在第二种情况下,它是闭包本身的一个参数,只需要比闭包的调用更长。