impl 上的第一个显式生命周期说明符是啥意思?

Posted

技术标签:

【中文标题】impl 上的第一个显式生命周期说明符是啥意思?【英文标题】:What does the first explicit lifetime specifier on an impl mean?impl 上的第一个显式生命周期说明符是什么意思? 【发布时间】:2017-01-14 07:45:26 【问题描述】:

在 impl 上有三种不同的生命周期说明符:

impl<'a> Type<'a> 
    fn my_function(&self) -> &'a u32 
        self.x
    

Type&lt;'a&gt; 声明在这个 impl 声明中一个生命周期。返回类型-&gt; &amp;'a u32 上的一个声明接收返回值的变量不应该在...之前死掉……在什么之前?在Type 类型的对象死亡之前?

这有什么区别:

impl TextEditor 
    //Other methods omitted ...

    pub fn get_text<'a>(&'a self) -> &'a String 
        return &self.text;
    

这里说返回类型在&amp;'a self 的生命周期结束之前不会消失。

最后一个是否只为这个方法声明一个生命周期,而另一个在 impl 声明中为每个方法(以及关联函数?)声明一个生命周期?

【问题讨论】:

Type&lt;'a&gt; 很可能包含依赖于'a 的内容。例如。在slice::Iter&lt;'a, T&gt; 上,'a 是对应切片的生命周期。然后as_slice(&amp;self) -&gt; &amp;'a [T] 可以检索它。 【参考方案1】:

解释 Rust 代码:

impl<'a>

“如果你给我一个生命......”(编译器通常在使用类型时根据上下文提供这个)

         Type<'a> 

"...我将描述如何实现Type&lt;'a&gt;"。所以Type 可能包含引用(需要生命周期)。

    fn my_function(&self) -> &'a u32 

“...给定一个Type&lt;'a&gt;的引用,你调用my_function()来获得一个u32的引用,它的生命周期为'a。”请注意&amp;self 引用的生命周期与'a 没有直接关系;它可以更短(但通常不超过'a,因为类型不能比包含的引用更长寿)。

第二种情况:

impl TextEditor 

“这里是如何实现非生命周期参数类型TextEditor...”

pub fn get_text<'a>

“给定一个你可以选择的生命周期'a(它是一个输入参数)......”

                   (&'a self)

“...以及对TextEditor 的引用,它至少存在'a..”

                             -> &'a String 

“...您可以调用get_text 方法并接收对同时存在的String 的借用引用。”

更实际地说,这实际上意味着 String 直接从 TextEditor 重新借用 - 只要 String 引用还活着,&amp;self 借用就被认为仍然有效并且你赢了'无法获取任何 &amp;mut 引用。

【讨论】:

谢谢,这非常有帮助!我发现我孤立地理解了 Rust 的大部分概念,但在实践中将它们组合在一起时常常会遇到困难。将简洁的语法翻译成解释性的散文是了解正在发生的事情的好方法。我希望阅读代码示例更重要:)【参考方案2】:

'a 在这两种情况下都是一个生命周期参数。这是一种通用参数,因此每次使用 Type 或每次使用 get_text 都可以为该通用参数选择不同的“值”。程序员从不明确选择实际生命周期,除非您使用 'static

编译器将为Type 的每个值或get_text 的每次使用推断'a 应该是什么。

impl&lt;'a&gt; 为整个 impl 块引入了一个新的生命周期参数。然后在类型中使用它:impl&lt;'a&gt; Type&lt;'a&gt; ..

'a 的确切含义取决于它在Type 的定义中的使用方式。从你的例子中,我猜Type 是这样的:

struct Type<'a> 
    x: &'a u32,

此定义为:对于每个生命周期 'a,定义类型以包含引用 x: &amp;'a u32。所以Type 是通用的,可以存储任何生命周期的引用。

impl&lt;'a&gt; Type&lt;'a&gt; .. 读取:对于每个生命周期 'a,为类型 Type&lt;'a&gt; 定义方法。

既然我们现在知道Type的结构定义,我们知道impl块内的'a参数总是等于Type的x字段中引用的生命周期。

返回类型上的那个 -> &'a u32 告诉 接收返回值的变量不应该死 之前……之前什么?在 Type 类型的对象死亡之前?

'a 是存储在 Type&lt;'a&gt; 值中的引用的生命周期,它与 Type 值本身没有其他关系。唯一的规则是 'a 必须比 Type 值本身更长寿,因为它不允许存储超过其生命周期的引用。所以事实上,我们至少可以保留 &amp;'a u32 直到 Type 值消失,甚至更长时间。


impl TextEditor 
    //Other methods omitted ...

    pub fn get_text<'a>(&'a self) -> &'a String 
        return &self.text;
    

这真的很常见。 &amp;self 是对 self 值的引用——借用——方法 get_text 又是一个通用项。它有一个通用参数——生命周期参数。

它读取,对于任何生命周期'a,借用 self 作为引用 &amp;'a self(该生命周期的引用)并返回对具有相同生命周期的 String 的引用。

在输入 &amp;self 和输出 &amp;String 上使用相同的参数意味着它们是连接的,只要返回的 String 引用是活动的,Rust 就会将 self 视为借用。

同样,方法get_text 是通用的,编译器将为'a 的每次使用选择一个“值”。这是一种可以返回不同长度的字符串借用的方法,具体取决于您允许它借用self 的时间。有时它会选择较长的生命周期,以便您可以长时间保留返回的&amp;String。如果您根本不使用返回值,get_text 的某些用途将使用更短的生命周期。

在这种情况下,由于我们看到 &amp;'a String 直接与 TextEditor 值的借用 &amp;'a self 绑定,我们知道我们最多只能保留 String 引用,只要我们可以持有借用TextEditor 值。

【讨论】:

以上是关于impl 上的第一个显式生命周期说明符是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用结构和隐式生命周期来推断实现的适当生命周期?

c语言中static说明是啥意思?

我啥时候需要在 Rust 中指定显式生命周期?

AOP说明

2react-生命周期1※※※

2react-生命周期1※※※