rust 语法和语义 11 生命周期
生命周期 lifetimes
所有权概念将依照官方介绍,分为3个部分说明:
- 所有权 ownership
- 引用和借用 references and borrowing
- 生命周期 lifetimes
概述
<'a, ‘b, ...> // <> 声明了生命周期
&’a u32 // a,b 为生命周期的名字
&‘b mut u32 // 'a 读作: 一个带有生命周期a的 xxxx
- 理解
生命周期 lifetimes
的一个办法是想象一个 引用有效的作用域scope
- 只有与
引用reference
相关的变量才需要生命周期
注解
<'a, 'b>
注意:生命周期注解是
_descriptive_ (描述性)
而不是_prescriptive_ (规定性)
这意味着引用的生命周期是由代码决定的(一般情况下编译器就已经知道生命周期了),
而不是由生命周期注解决定的(注解是在复杂场景下开发人员帮助编译里理清生命周期)。
注解可以确保实现遵守了如函数声明建立的约束。
struct 需显式生命周期
struct Foo<'a> {
x: &'a i32, // & 成员的引用
}
显式的生命周期用于确保任何 struct 的引用不能比它包含的 成员的引用 &
活的更久。
impl 块
struct Foo<'a> {
x: &'a i32,
}
impl<'a> Foo<'a> {
fn x(&self) -> &'a i32 {self.x}
}
就像在函数中: impl<’a> 定义了一个生命周期 ‘a ,而 Foo<’a> 使用它。
多个生命周期
可以全是一样的生命周期
fn x_or_y<'a, 'a>(x: &'a str, y: &'a str) -> &'a str {...}
也可以不全是一样的生命周期
fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {...}
‘static
'static
表示拥有横跨整个程序的生命周期。
如,字符串:
let x: &'static str = "hello world";
如,全局变量的引用:
static FOO: i32 = 5;
let x: &'static i32 = &FOO;
生命周期省略原则
Rust 强大的支持在函数体中的局部类型推断!
生命周期类型
| 生命周期类型 | lifetimes type | 关于 | 例子
|
| 输入生命周期 | input lifetime | 函数参数 | fn foo<'a>(bar: &'a str)
| 输出生命周期 | output lifetime | 函数返回值 | fn foo<'a>() -> &'a str
原则
注意:只有与
引用reference
相关的变量才需要生命周期
- 每一个被省略的
输入生命周期
会成为一个不同的
生命周期参数。 - 如果
只有一个
输入生命周期(不管是否省略),
则这个生命周期被赋予所有 被省略的输出生命周期 。 - 如果
有多个
输入生命周期,当其中有一个是&self
或者&mut self
时,
self 的生命周期被赋予所有 被省略的输出生命周期 。
否则,省略一个 输出生命周期
将是一个错误。
// ILLEGAL, no inputs
fn get_str() -> &str;
// Output lifetime is ambiguous
fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str;