lifetime生命周期
一个变量的声明周期从它被声明时开始,直到它被销毁结束。
声明周期是编译器用来保证所有borrow可用的一个构造。
function
rust使用显示声明,来确定一个引用的声明周期。
fn foo<’a, ‘b>,表示foo函数的声明周期,不能超过’a,’b中的任何一个。
如果不考虑省略形式,函数的声明至少要满足几个约束
- 任何的引用,必须声明一个生命周期。
- 任何返回的引用类型,必须和输入变量的一个声明周期相同,或者’static。
- 对于返回一个引用类型,并且没有入参的函数,是禁止的
1
2
3
4//编译报错
fn test<'a>() -> &'a str {
&String::from("hello world")
}
method
method和function有一样的语法和约束。
struct
1 | struct Borrowed<'a> { |
语法类似,表示Borrowed实例的生命周期,不能超过成员变量x,y中的任何一个。
trait
trait也可用声明生命周期,响应的impl也可以声明。
bound边界
类似泛型的边界,声明周期也会有边界,注意下面语法的读法:
T: ‘a: All references in T must outlive lifetime ‘a.
T: Trait + ‘a: Type T must implement trait Trait and all references in T must outlive ‘a.
限制作用域
1 | // `<'a: 'b, 'b>` reads as lifetime `'a` is at least as long as `'b`. |
static
‘static生命周期是rust预留的生命周期, 如果一个引用的生命周期是static,表明这个引用指向的数据,在整个程序运行的周期内都存活。
rust有两种方式声明static的变量,它们都被存储在只读的可执行文件内存中:
- static声明的常量,static NUM: i32 = 18;
- &’static str声明的字符串切片。
当static作为trait边界时,表示类型不包含任何非static的引用。
- 任何owned的变量,都是static的;而一个指向owned的引用则不是。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17use std::fmt::Debug;
fn print_it( input: impl Debug + 'static )
{
println!( "'static value passed in is: {:?}", input );
}
fn use_it()
{
// i is owned and contains no references, thus it's 'static:
let i = 5;
print_it(i);
// oops, &i only has the lifetime defined by the scope of
// use_it(), so it's not 'static:
print_it(&i);
}
Elision(声明周期的‘省略’)
生命周期简写规则
- each parameter that is a reference gets its own lifetime parameter.
如果函数没有指定生命周期,那么每一个引用参数,都会被指定一个声明周期。 - if there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters.
如果函数只有一个入参生命周期,那么这个生命周期会被指定给每一个输出引用变量。 - if there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters.
如果一个method有多个入参生命周期,并且其中一个是&self或者&mut self,但是出参没有指定,那么出参的生命周期和self相同。