将具有显式生命周期的闭包作为Rust中的参数

时间:2017-03-07 12:22:32

标签: rust lifetime

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;来自?

1 个答案:

答案 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闭包以简化操作;使用FnRefCell可能会产生同样的不安全感,但这会使示例变得更加复杂。

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的参数,因此必须比该调用更长;但在第二种情况下,它是闭包本身的一个参数,只需要比闭包的调用更长。