根据 The Rust Book,终身省略允许我们拥有这个签名:
fn first_word(s: &str) -> &str {
...
}
而不是这个更详细的版本:
fn first_word<'a>(s: &'a str) -> &'a str {
...
}
但是后来在同一本书中,我发现我不能写这个:
fn make_a_cloner(s: &str) -> impl Fn() -> String {
move || s_ref.to_string()
}
我必须给返回类型一个生命周期:
fn make_a_cloner(s: &str) -> impl Fn() -> String + '_ {
...
}
我有点困惑。为什么我们在返回
&str
时不需要指定任何生命周期,但在返回 '_
时需要添加 impl Fn() -> String
?为什么相同的省略规则不适用于这两种情况?
尽管生命周期省略可能会让人感到困惑,但 Rust 的语法确实希望在发生借用时能够保持清晰。引用就是这样一个地方,它是一个明确的借用者,即使对于具有生命周期的结构,也鼓励您使用
MyStruct<'_>
作为参数和参数,以便生命周期是显而易见的。编译器中有一个 elided_lifetimes_in_paths
lint 可以帮助解决这个问题,但不幸的是默认情况下是允许的;我鼓励您将其添加到您自己的代码中。
但是,当您返回
impl Trait
(没有生命周期)时,就没有任何注释来表明已发生借用。添加占位符生命周期 + '_
至少可以向编译器和其他开发人员传达正在发生借用的信息。因此,如果没有生命周期注释返回 impl Trait
,则默认情况下将使用 'static
,除非特征类型的其他部分传递借用(即 impl Trait<&'a T>
将受 'a
约束,而不是 'static
) ).
这不一定适用于其他地方的
impl Trait
(如函数参数)。