Rust 生命周期
生命周期
避免悬垂引用。
rust可以提前声明,即声明一个变量但不初始化,因为没有赋值,所以也用不了,rust也不存在空值。
借用检查器
比较作用域来判断所有的借用是否合法。被引用的数据存活时间,必须比引用者的长。
函数中的泛型生命周期
手动设置生命周期,当函数返回一个引用的时候,它不会知道这个引用的生命周期,所以要手动设置。
fn main(){
let account = String::from("achu");
let result = checkLife(account.as_str(), "xyz");
}
fn checkLife<'a>(x: &'a str, y: &'a str) -> &'a str{
// 声明作用域生命周期'a
if x.len() > y.len(){
x
} else {
y
}
}
上面那个函数的签名的意思:这个函数有个声明周期'a,两个参数的生命周期必须大于'a,函数返回的切片的生命周期也不能短于'a。这并没有改变生命周期,只是增加了约束。
这个'a的作用域是x作用域和y作用域中最短的那一部分。
生命周期的标注语法
- 生命周期的标准不会改变引用的生命周期长度。
- 当指定了泛型的生命周期,函数可以接收带有任何生命周期的引用。
- 生命周期的标准描述了多个引用生命周期间的关系,但不影响声明周期。
以'开头,全小写非常短,一般用'a
放在引用的&符号后面,用空格分开。
&i32
一个引用。
&'a i32
带有显式生命周期的引用。
&'a mut i32
带有显式生命周期的可变引用。
单个生命周期标准本身没有意义。
函数中声明
fn longest<'a>
深入理解生命周期
如果函数只返回一个参数,那么只需要规定返回参数的生命周期就行。
- 从函数返回引用时,返回的类型的生命周期参数需要与其中一个参数的生命周期相匹配。
- 如果返回的引用没有指向任何参数。那么它只能引用函数内创建的值:垂悬引用。解决方法是不返回引用,直接返回值。
生命周期在:
- 函数/方法的参数:输入生命周期。
- 函数/方法的返回值:输出生命周期。
Struct定义中的生命周期和标注
struct里可以包括
- 自持有的类型。
- 引用:需要在每个引用上添加生命周期标注。
struct test<'a>{part: &'a str,}
方法中生命周期标注
需要在struct上使用。
struct test<'a>{part: &'a str}
impl<'a> test<'a> {
fn level(&self) -> i32{
3
}
}
生命周期省略的三个规则。
- 每个引用类型的参数都有自己的生命周期。
- 如果只有1个输入生命周期参数,那么该生命周期被赋给所有的输出生命周期参数。
- 如果有多个输入生命周期参数,但其中一个是&self或&mut self (结构体内的方法),那么self的生命周期会被赋给所有的输出生命周期参数。
静态生命周期 'static
'static 是一个特殊的生命周期:整个程序的持续时间。比如&str
总结
- 必须是多个引用。
- 函数返回值的生命周期取的是参数中最短的那个生命周期。
- &str 字符串字面值是一个静态生命周期,是全局作用域有效存活。
3.1 &str是直接在可执行文件中执行的,这块内存直接放到可执行文件的,所以不会因为所有权而消失。因此指向这块内存的引用,一直是一个合法的内存。