Rust学习_5.生命周期
生命周期
Rust 的每个引用都有自己的生命周期;
生命周期:引用保持有效的作用域;
大多数情况:生命周期是隐式的、可被推断的;
当引用的生命周期可能以不同的方式互相关联时:手动标注生命周期;
目标:避免悬垂引用(dangling reference)。
一、生命周期的标注语法
生命周期的标注不会改变引用的生命周期长度;
当指定了泛型生命周期参数,函数可以接收带有任何生命周期的引用;
生命周期的标注:描述了多个引用的生命周期间的关系,但不影响生命周期。
1
2
3&i32 // 一个引用
&'a i32 // 带有显示生命周期的引用
&'a mut i32 // 带有显示生命周期的可变引用
二、函数签名中的生命周期标注
- 泛型生命周期参数声明在:函数名和参数列表之间的<>里;
- 生命周期
'a
的实际生命周期是:x和y两个生命周期中较小的那个。
1 | fn main() { |
三、深入理解生命周期
- 指定生命周期参数的方式依赖于函数所做的事情;
- 从函数返回引用时,返回类型的生命周期参数需要与其中一个参数的生命周期匹配;
- 如果返回的引用没有指向任何参数,那么它只能引用函数内创建的值:
- 这就是悬垂引用:该值在函数结束时就走出了作用域;
- 此时一般不返回引用,就直接返回值了。
四、Struct定义中的生命周期标注
Struct 中若定义引用类型则需要在每个引用上添加生命周期标注;
Struct 中属性的生命周期一定要比Struct类型生命周期长,否则就要出错了。
1
2
3
4
5
6
7
8
9
10
11struct ImportantExcerpt<'a>{
part:&'a str,
}
fn main(){
let novel = String::from("Call me Ishmael. Some years ago...");
let first_sentence = novel.split(".").next().expect("Could not found a '.'");
let i = ImportantExcerpt{
part:first_sentence
};
}
五、生命周期的省略
- 生命周期省略规则
1. 输入、输出生命周期
- 输入生命周期:函数/方法的参数
- 输出生命周期:函数/方法的返回值
2. 生命周期省略的三个规则
编译器使用三个规则在没有显示标注生命周期的情况下,来确定引用的生命周期
- 规则1应用于输入生命周期;
- 规则2、3应用于输出生命周期;
- 如果编译器应用完3个规则之后,仍然有无法确定生命周期的引用则报错;
- 这些规则适用于
fn
定义的和impl
块。
- 规则1:每个引用类型的参数都有自己的生命周期;
- 规则2:如果只有一个输入生命周期参数,那么该生命周期被赋给所有的输出生命周期参数;
- 规则3:如果有多个输入生命周期参数,但其中一个是
&self
或&mut self
(是方法,不是函数),那么self
的生命周期会被赋给所有的输出生命周期参数。
六、方法定义中的生命周期标注:
在
Struct
上使用生命周期实现方法,语法和泛型参数的语法一样在哪儿声明和使用生命周期参数,依赖于:
- 生命周期参数是否和字段、方法的参数或返回值有关;
Struct
字段的生命周期名:- 在impl后声明
- 在struct名后使用
- 这些生命周期是struct类型的一部分
impl 块内的方法签名中:
- 引用必须绑定于 struct 字段引用的生命周期,或者引用是独立的也可以;
- 生命周期省略规则经常使得方法中的生命周期标注不是必须的。
1 | struct ImportantExcerpt<'a>{ |
七、静态生命周期
’static 是一个特殊的生命周期:整个程序的持续时间。
- 例如:所有的字符串字面量值都拥有
'static
生命周期;
八、泛型参数类型、Trait Bount、生命周期
1 | use std::fmt::Display; |