本文介绍了在Rust中将具有显式生命期的闭包作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust文档的关闭部分具有以下示例:

The closures section of Rust documentation has this example:

fn call_with_ref<'a, F>(some_closure: F) -> i32
    where F: Fn(&'a i32) -> i32
{
    let value = 0;
    some_closure(&value)
}

这不能编译,因为如文档所述:

This doesn't compile because, as the docs put it:

错误消息是

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

我很难理解这一点.价值没有足够长的寿命意味着什么?据我了解,价值贯穿于整个函数的调用.那么,寿命不够长"从何而来?

I am having trouble understanding this. What does it mean that value does not live long enough? From what I understand value lives through the entire call of the function. So, where does the "not living long enough" come from?

推荐答案

当生存期出现在参数列表中时,这意味着调用方可以自行决定.它选择的生存期可以是它喜欢的寿命,甚至可能长于闭包的生存期,甚至是'static .

When a lifetime appears in the parameter list, that means the caller gets to decide. The lifetime it chooses can be as long as it likes, and possibly longer than the closure lives for, even 'static.

这是一个不好的例子,此错误可以避免此情况:

Here's a bad example which is prevented by this error:

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 变量的悬挂引用存储在寿命更长的变量中.

If this version of call_with_ref were allowed to compile, it would allow storing a dangling reference to the local value variable in a variable which lives for longer.

请注意,为简单起见,我将函数更改为采用 FnMut 闭包;使用 Fn RefCell 可能会具有相同的不安全性,但这会使示例变得更加复杂.

Note I've changed the function to take an FnMut closure for simplicity; it would be possible to have the same unsafety using Fn and a RefCell, but it would have made the example more complicated.

(操场上标有坏"字样的)

该书的关闭部分然后显示;'a> 语法,它更改了生命周期限制的含义.

The closures section of the book then shows the for<'a> syntax, which changes the meaning of the lifetime bound.

以下译成英文:

fn call_with_ref<'a, F>(some_closure: F) -> i32
     where F: Fn(&'a i32) -> i32

大致是指赋予生命周期'a ,并且是一个调用对象,该引用引用了对'a 有效的 i32 ,我将返回 i32 ".这意味着生存期是由 call_with_ref 的调用方设置的并且是固定的.

means roughly "given a lifetime 'a, and a callable which takes a reference to an i32 which is valid for 'a, I'll return an i32". This means that the lifetime is set by the caller of call_with_ref and is fixed.

相反,以下内容:

fn call_with_ref<F>(some_closure: F) -> i32
     where F: for<'a> Fn(&'a i32) -> i32

表示给定一个可以引用任何生存期的 i32 的可调用对象,我将返回 i32 ."区别在于闭包将接受 any 引用生存期(超过了闭包的调用时间).

means "given a callable which can take a reference to an i32 of any lifetime, I'll return an i32". The difference is that the closure will accept any reference lifetime (which outlives the call of the closure).

在第一种情况下,生存期是 call_with_ref 的参数,因此必须比该调用有效.但是在第二种情况下,它是闭包本身的参数,只需要延长对闭包的调用的时间即可.

In the first case, the lifetime is a parameter to call_with_ref, so must outlive that call; but in the second case it's a parameter to the closure itself and only needs to outlive the call to the closure.

这篇关于在Rust中将具有显式生命期的闭包作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 11:24