基础生命周期的介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//1.Rust中每一个引用都有生命周期,也就是引用保持有效的作用域,大部分时候生命周
//期是隐含并可以推断的,正如大部分时候类型可以推断一样
//2.生命周期的主要目标是避免悬垂引用

//3.Rust编译器使用借用检查器来检查生命周期是否有效
//因为生命周期和借用,以及引用有关

//4.生命周期常常伴随着str使用

//错误示例
fn main() {
let r;
{
let x = 5;
r = &x;
}
//x被droped但是仍然在使用
//会造成悬垂引用,但是rust的编译器会阻止这种行为
println!("r = {}",r);

}
//---------------------------

函数中的生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//编译器默认提供了自己的生命周期,但是使用的过程中往往需要自行标注生命周期
//
//这段语法会报错,因为生命周期未知,可能会造成悬垂引用
//fn longest(x: &str,y: &str) -> &str { //期待生命周期的参数
// if x.len() > y.len() {
// x
// }else {
// y
// }
// }
fn longest<'a>(x: &'a str,y: &'a str) -> &'a str { //需要生命周期的参数
if x.len() > y.len() {
x
}else {
y
}
}
fn get_str<'a>(x: &'a str,y: &'a str) -> &'a str {
//因为这里没有用到y,所以y的生命周期没有标注也是可以的
//fn get_str<'a>(x: &'a str,y: &str) -> &'a str {
x
}

//这段代码虽然写了生命周期,但是这段代码中要返回的是局部变量(位于堆上),早就dropped!
fn a_str(x: &'a str,y: &'a str) -> &'a str {
let r = String::from("abc");
r.as_str()
}
fn mian() {
let s1 = String::from("abcde");
let s2 = String::from("ab");
let r = longest(s1.as_str(),s2.as_str());
println!("r = {}",r);
let g = get_str(s1.as_str(),s2.as_str());
println!("g = {}",g);

let ss = get_str(s1.as_str(),s2.as_str());
let ss2 = a_str(s1.as_str(),s2.as_str());
}

结构体中的生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//需要考虑生命周期,因为是str,对于引用和借用需要有生命周期的标注
//struct A {
// name: &str,
// }
//
#[derive(Debug)]
struct A<'a> {
name: &'a str,
}
fn main() {
let n = String::from("hello");
let a = A {
name: &n,
};
println!("a = {:#?}",a);
}