Appearance
Rust lifetime 生命周期
- 变量的生命周期局限在作用域内,如果要在作用域之外使用改变了,那么我们就需要标注?
Borrow Checker 借用检查器
代码块
Rust 编译器会在编译的时候比较作用域变量的生命周期。 Rust 官方文档中有如下示例:
rust
{
let r; // ---------+-- 'a
// |
{ // |
let x = 5; // -+-- 'b |
r = &x; // | |
} // -+ |
// |
println!("r: {}", r); // |
}
从中我们可以看出,里面括号里的代码块,变量 x 的作用域局限在里面的括号里,所以它的生命周期明显只有在这个括号里,对比变量 r,r 的生命周期要比 x 长,这个时候又将 x 的引用赋值给 r,编译器会报错,因为后面的println!("r: {}", r);
打印的 r,其实是 x。
在函数中分配生命周期
函数传参数,参数为引用,为什么要传引用呢?不想让函数拥有参数的所有权。
rust
&i32 // 这是一个引用
&'a i32 // 这是一个有着详细生命周期的引用
&'a mut i32 // 这是一个有着详细生命周期的可变引用
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
x
}
// 错误案例
fn longest<'a>(x: &str, y: &str) -> &'a str {
let result = String::from("really long string");
result.as_str()
}
为什么的个函数longest
会报错呢?原因是 result 的生命周期要比'a
短。
在结构体定义里标记生命周期
哪些规则不需要为引用声明生命周期(lifetime elision rules)生命周期省略
- 每一个引用都有一个生命周期
- 在函数或者方法参数中,生命周期被称作输入生命周期,相反,返回值的被称作输出生命周期。
生命周期省略规则
第一条适用于输入生命周期,后面两条则适用于输出生命周期。适用于
fn
和impl
块。只有满足如下三点,就可以不用声明生命周期。
- 每一个引用参数都有自己的一个生命周期。
- 如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数。
- 多个输入生命周期参数,
&self
或&mult self
,self 的生命周期被赋给所有输出生命周期参数。
- the dangling reference
- 未标注的引用