rust入门示例教程(Rust学习笔记三十生命周期)
rust入门示例教程(Rust学习笔记三十生命周期)例:生命周期标注的位置:例://src/main.rs fn main() { let string0 = String::from("6666"); let string1 = "888"; let result = longest(string0.as_str() string1); println!("The longest string is {}" result); } fn longest<'a>(x: &'a str y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } 生命周期标注语法上一个例子中
Rust的每个引用都有自己的生命周期。生命周期让每个引用都保持自己有效的作用域。大多数情况下,生命周期是隐式的,可被推断的。当引用的生命周期可能以不同的方式互相关联时,需要手动标注生命周期。
生命周期——避免悬垂引用(dangling reference)生命周期的主要目标是避免悬垂引用。例:
//src/main.rs
fn main() {
{
let r; //r作用域开始
{
let x = 5; //x开始作用
r = &x; //r指向x的引用
} //代码块结束,x作用域结束被销毁
println!("r: {}" r); //r指向的x的生命周期结束,导致r指向了无效引用
}
}
借用检查器
Rust编译器的借用检查器通过比较作用域来判断所有的借用是否合法。 如果以上例子中的r和x的生命周期:
很明显,被引用对象x的生命周期短于引用它的r的生命周期,所以编译不通过。
函数中的泛型生命周期例:
//src/main.rs
fn main() {
let string0 = String::from("6666");
let string1 = "888";
let result = longest(string0.as_str() string1);
println!("The longest string is {}" result);
}
fn longest<'a>(x: &'a str y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
生命周期标注语法
上一个例子中使用了生命周期标注语法。生命周期的标注不会改变引用的生命周期长度,它只是描述了多个引用的生命周期之间的关系,但是不影响生命周期。当你指定了泛型生命周期参数,函数可以接收带有任何生命周期的引用。
生命周期参数名:
- 以'开头
- 通常全小写且非常短
- 很多开发者使用'a
生命周期标注的位置:
- 在引用符号&后
- 使用空格将标注和引用类型分开
例:
- &i32 //一个引用
- &'a i32 //带有显式生命周期的引用
- &'a mut i32 //带有显式生命周期的可变引用
单个生命周期标注本身没有意义,因为它是描述多个引用的生命周期之间的关系。
函数签名中的生命周期标注泛型生命周期参数声明在函数名和参数列表之间的<>里,还是之前的例子:
fn longest<'a>(x: &'a str y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
函数定义指定了签名中所有的引用和返回值必须有相同的生命周期 'a,否则报错。 根据上面的例子,'a这个生命周期实际上是引用x与y生命周期中较小的那个。改写之前的例子:
//src/main.rs
fn main() {
let result;
let string0 = String::from("6666");
{
let string1 = String::from("888");
result = longest(string0.as_str() string1.as_str());
}
println!("The longest string is {}" result);
}
fn longest<'a>(x: &'a str y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
编译报错:
error[E0597]: `string1` does not live long enough
--> src\main.rs:8:44
|
8 | result = longest(string0.as_str() string1.as_str());
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
9 | }
| - `string1` dropped here while still borrowed
10 |
11 | println!("The longest string is {}" result);
| ------ borrow later used here
报错原因:
- string0生命周期:5-12
- string1生命周期:7-9
- 二者交集是7-9
- result生命周期:4-12
因此返回值result生命周期大于了'a规定的生命周期,报错。