我在 Rust 文档中没有发现任何规则能够解释生命周期省略如何应用于闭包。让我们来看一个简单的例子:
fn foo(s: &str) {
let id = |x: &str| x;
println!("{}", id(s));
}
fn main() {
foo("string");
}
我曾认为foo
函数中的闭包会像以下代码一样工作:
fn foo(s: &str) {
struct Id; // A helper structure for closure
impl Id {
fn id(self: Self, x: &str) -> &str { &x }
}
let id = Id; // Creating a closure
println!("{}", id.id(s));
}
后者运行良好,但前者无法编译并产生了一个关于生命周期冲突的长错误消息。
t3.rs:2:24: 2:25 error: cannot infer an appropriate lifetime due to conflicting requirements [E0495]
t3.rs:2 let id = |x: &str| x;
^
t3.rs:2:24: 2:25 note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 2:23...
t3.rs:2 let id = |x: &str| x;
^
t3.rs:2:24: 2:25 note: ...so that expression is assignable (expected `&str`, found `&str`)
t3.rs:2 let id = |x: &str| x;
^
<std macros>:3:11: 3:36 note: but, the lifetime must be valid for the expression at 3:10...
<std macros>:3 print ! ( concat ! ( $ fmt , "\n" ) , $ ( $ arg ) * ) ) ;
^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
t3.rs:3:5: 3:27 note: in this expansion of println! (defined in <std macros>)
<std macros>:3:11: 3:36 note: ...so type `(&&str,)` of expression is valid during the expression
<std macros>:3 print ! ( concat ! ( $ fmt , "\n" ) , $ ( $ arg ) * ) ) ;
^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
t3.rs:3:5: 3:27 note: in this expansion of println! (defined in <std macros>)
error: aborting due to previous error
我想知道为什么 Rust 不能推断出像我上面写的简单闭包中正确的生命周期。此外,为什么编译器认为有寿命的要求存在冲突。
: &str
就可以运行了。那里的&str
并不是你想象中的意思。我现在没时间解释,因为我应该去睡觉了。 - Chris Morganfor<'a>
,但还不太清楚……而且在20个小时后没有得到答案,似乎我不是唯一不确定发生了什么的人^^ - Matthieu M.