为什么生命周期省略对于返回 Fn 的函数不起作用?

问题描述 投票:0回答:1

根据 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 closures lifetime
1个回答
0
投票

尽管生命周期省略可能会让人感到困惑,但 Rust 的语法确实希望在发生借用时能够保持清晰。引用就是这样一个地方,它是一个明确的借用者,即使对于具有生命周期的结构,也鼓励您使用

MyStruct<'_>
作为参数和参数,以便生命周期是显而易见的。编译器中有一个
elided_lifetimes_in_paths
lint 可以帮助解决这个问题,但不幸的是默认情况下是允许的;我鼓励您将其添加到您自己的代码中。

但是,当您返回

impl Trait
(没有生命周期)时,就没有任何注释来表明已发生借用。添加占位符生命周期
+ '_
至少可以向编译器和其他开发人员传达正在发生借用的信息。因此,如果没有生命周期注释返回
impl Trait
,则默认情况下将使用
'static
,除非特征类型的其他部分传递借用(即
impl Trait<&'a T>
将受
'a
约束,而不是
'static
) ).

这不一定适用于其他地方的

impl Trait
(如函数参数)。

© www.soinside.com 2019 - 2024. All rights reserved.