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<'a>
声明在这个 impl 声明中有一个生命周期。返回类型-> &'a u32
上的一个声明接收返回值的变量不应该在...之前死掉……在什么之前?在Type
类型的对象死亡之前?
这有什么区别:
impl TextEditor
//Other methods omitted ...
pub fn get_text<'a>(&'a self) -> &'a String
return &self.text;
这里说返回类型在&'a self
的生命周期结束之前不会消失。
最后一个是否只为这个方法声明一个生命周期,而另一个在 impl 声明中为每个方法(以及关联函数?)声明一个生命周期?
【问题讨论】:
Type<'a>
很可能包含依赖于'a
的内容。例如。在slice::Iter<'a, T>
上,'a
是对应切片的生命周期。然后as_slice(&self) -> &'a [T]
可以检索它。
【参考方案1】:
解释 Rust 代码:
impl<'a>
“如果你给我一个生命......”(编译器通常在使用类型时根据上下文提供这个)
Type<'a>
"...我将描述如何实现Type<'a>
"。所以Type
可能包含引用(需要生命周期)。
fn my_function(&self) -> &'a u32
“...给定一个Type<'a>
的引用,你调用my_function()
来获得一个u32
的引用,它的生命周期为'a
。”请注意&self
引用的生命周期与'a
没有直接关系;它可以更短(但通常不超过'a
,因为类型不能比包含的引用更长寿)。
第二种情况:
impl TextEditor
“这里是如何实现非生命周期参数类型TextEditor
...”
pub fn get_text<'a>
“给定一个你可以选择的生命周期'a
(它是一个输入参数)......”
(&'a self)
“...以及对TextEditor
的引用,它至少存在'a
..”
-> &'a String
“...您可以调用get_text
方法并接收对同时存在的String
的借用引用。”
更实际地说,这实际上意味着 String
直接从 TextEditor
重新借用 - 只要 String
引用还活着,&self
借用就被认为仍然有效并且你赢了'无法获取任何 &mut
引用。
【讨论】:
谢谢,这非常有帮助!我发现我孤立地理解了 Rust 的大部分概念,但在实践中将它们组合在一起时常常会遇到困难。将简洁的语法翻译成解释性的散文是了解正在发生的事情的好方法。我希望阅读代码示例更重要:)【参考方案2】:'a
在这两种情况下都是一个生命周期参数。这是一种通用参数,因此每次使用 Type
或每次使用 get_text
都可以为该通用参数选择不同的“值”。程序员从不明确选择实际生命周期,除非您使用 'static
。
编译器将为Type
的每个值或get_text
的每次使用推断'a
应该是什么。
impl<'a>
为整个 impl 块引入了一个新的生命周期参数。然后在类型中使用它:impl<'a> Type<'a> ..
'a
的确切含义取决于它在Type
的定义中的使用方式。从你的例子中,我猜Type
是这样的:
struct Type<'a>
x: &'a u32,
此定义为:对于每个生命周期 'a
,定义类型以包含引用 x: &'a u32
。所以Type
是通用的,可以存储任何生命周期的引用。
impl<'a> Type<'a> ..
读取:对于每个生命周期 'a
,为类型 Type<'a>
定义方法。
既然我们现在知道Type
的结构定义,我们知道impl块内的'a
参数总是等于Type
的x字段中引用的生命周期。
返回类型上的那个 -> &'a u32 告诉 接收返回值的变量不应该死 之前……之前什么?在 Type 类型的对象死亡之前?
'a
是存储在 Type<'a>
值中的引用的生命周期,它与 Type 值本身没有其他关系。唯一的规则是 'a
必须比 Type 值本身更长寿,因为它不允许存储超过其生命周期的引用。所以事实上,我们至少可以保留 &'a u32
直到 Type
值消失,甚至更长时间。
impl TextEditor
//Other methods omitted ...
pub fn get_text<'a>(&'a self) -> &'a String
return &self.text;
这真的很常见。 &self
是对 self 值的引用——借用——方法 get_text
又是一个通用项。它有一个通用参数——生命周期参数。
它读取,对于任何生命周期'a
,借用 self 作为引用 &'a self
(该生命周期的引用)并返回对具有相同生命周期的 String 的引用。
在输入 &self
和输出 &String
上使用相同的参数意味着它们是连接的,只要返回的 String 引用是活动的,Rust 就会将 self 视为借用。
同样,方法get_text
是通用的,编译器将为'a
的每次使用选择一个“值”。这是一种可以返回不同长度的字符串借用的方法,具体取决于您允许它借用self
的时间。有时它会选择较长的生命周期,以便您可以长时间保留返回的&String
。如果您根本不使用返回值,get_text
的某些用途将使用更短的生命周期。
在这种情况下,由于我们看到 &'a String
直接与 TextEditor
值的借用 &'a self
绑定,我们知道我们最多只能保留 String 引用,只要我们可以持有借用TextEditor
值。
【讨论】:
以上是关于impl 上的第一个显式生命周期说明符是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章