生锈中lambda表达的生命周期

And*_*ott 8 lambda lifetime rust

如果我有一个函数返回一个函数:

fn<'r, T> ( p : T ) -> (&'r fn(&'r str) -> ~[(T,int)]) {
     return |s| ~[(p, 0)]
}
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不起作用,我得到以下(有点重复)错误:

playground.rs:10:8: 10:29 error: cannot infer an appropriate lifetime due to conflicting requirements
playground.rs:10         return |s| ~[(p, 0i)]
                         ^~~~~~~~~~~~~~~~~~~~~
playground.rs:9:70: 11:5 note: first, the lifetime cannot outlive the block at 9:70...
playground.rs:9     pub fn result<'r, T>( p : T ) -> (&'r fn(&'r str) -> ~[(T, int)] ){
playground.rs:10         return |s| ~[(p, 0i)]
playground.rs:11     }
playground.rs:10:8: 10:29 note: ...due to the following expression
playground.rs:10         return |s| ~[(p, 0i)]
                         ^~~~~~~~~~~~~~~~~~~~~
playground.rs:9:70: 11:5 note: but, the lifetime must be valid for the lifetime &'r  as defined on the block at 9:70...
playground.rs:9     pub fn result<'r, T>( p : T ) -> (&'r fn(&'r str) -> ~[(T, int)] ){
playground.rs:10         return |s| ~[(p, 0i)]
playground.rs:11     }
playground.rs:10:8: 10:29 note: ...due to the following expression
playground.rs:10         return |s| ~[(p, 0i)]
                         ^~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

我相信这是说函数签名返回的生命周期和返回值不匹配.但是,我不确定如何使用life来注释lambda以使其工作.

Aat*_*tch 13

所以这是生锈中常见的错误,认为生命周期参数实际上会影响生命周期.

它们没有,它们只允许编译器知道从函数返回的引用持续一段时间.无论如何这都是真的,但现在编译器也知道它并且可以允许更多代码安全.这是Rust仅进行局部分析(一次查看单个函数)的结果.

在这种情况下,您将创建堆栈闭包.顾名思义,堆栈上会创建堆栈闭包,然后将其返回堆栈.这与此C代码类似:

int *foo() { int a = 5; return &a; }
Run Code Online (Sandbox Code Playgroud)

显然,指针(或"引用")to a在您返回时无效.这是Rust防止的.

在这种情况下,堆栈闭包的生命周期持续到函数的持续时间,但是生命周期参数要求它持续的时间比这长(尽管没有什么可说的确切地说多长时间),因此不匹配错误.

一个基本的经验法则是,如果你在函数上有生命周期参数,你需要在参数列表和返回类型的位置中的每个参数,否则你可能做错了.

如果你真的想返回封闭,则必须使用堆关闭,~fn (&str) -> ~[(T, int)]因为是在堆上分配和更加自由,可以通过左右(虽然还没有复制).