lifetime
寿命Rust
中的每一个引用都有一个有效的作用域,生命周期就是为这个作用域服务的,大部分生命周期编译器可以推断出来,可以是隐式的。但是如果在某些情况下编译器就无法正常推断出来了,需要我们自己手动标注,标注生命周期语法就是'a
这样的语法。
例如下面例子就是在两个字符串切片里面查找最长的那个并且返回!
// 'a 是指3个引用的作用域生命周期要一致
fn find_long_str<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
上面我就加注了生命周期标识符,如果不加编译器会报错,原因是因为我们这个函数引用的是外部的变量,不能确定引用的变量是否已经被销毁了,那这样就是悬垂引用!
let str1 = String::from("Hello");
let str2;
let result;
{
//let str2 = String::from(" World!");
str2 = String::from(" World!");
result = find_long_str(str1.as_str(), &str2);
}
// 这里借用检测就提示 引用了已经销毁的资源了
println!("{}", result);
大致过程图
加了生命周期标识符之后,如果我把let str2 = String::from(" World!");
取消注释放在一个内部作用域里面定义,那么这时调用find_long_str
编译器就会报错,因为我在下面出了作用域还使用了find_long_str
返回的结果,而这个结果可能就是str2
的内容, 使用这个是违反了所有权规则的,str2
离开内部作用域就被销毁了。
在标注生命周期fn find_long_str<'a>(x: &'a str, y: &'a str) -> &'a str
之后编译器就知道输入参数和返回参数生命周期是要一致的,并且返回值生命周期肯定是取生命周期最短的那个的。
self
的生命周期会被赋给输出的生命周期。