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

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

然而,这似乎不起作用,我得到以下(有点重复)错误:
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

我相信这是说函数签名的返回和返回值的生存期不匹配。但是,我不知道如何用一生来注释lambda以使其工作。

最佳答案

所以这是生锈的一个常见错误,认为寿命参数实际上影响寿命。
它们不允许,它们只允许编译器知道从函数返回的引用持续一定的时间。不管怎样,这是真的,但是现在编译器也知道了,可以允许更多的代码安全。这是只做局部分析(一次只看一个函数)的生锈的结果。
在本例中,您将创建堆栈闭包。顾名思义,在堆栈上创建一个堆栈闭包,然后将其返回到堆栈上。这与C代码类似:

int *foo() { int a = 5; return &a; }

显然,返回时指向a的指针(或“引用”)无效。这就是生锈的原因。
在这种情况下,堆栈闭包的生存期持续函数的持续时间,但lifetime参数要求其持续时间长于此值(尽管没有什么可以说明这到底有多长),因此产生了不匹配错误。
一个基本的经验法则是,如果在函数上有生存期参数,则需要将每个参数放在参数列表和返回类型中的某个位置,否则可能会出错。
如果您真的希望返回闭包,那么必须使用堆闭包~fn (&str) -> ~[(T, int)],因为它是在堆上分配的,可以更自由地传递(尽管仍然没有复制)。

07-28 11:56