Rust Lifetimes
The Rust lifetime mechanism is a resource management mechanism as important as the ownership mechanism.
The main reason for introducing this concept is to deal with resource management issues in complex type systems.
References are an essential mechanism when dealing with complex types, after all, data of complex types cannot be easily copied and computed by the processor.
But references often lead to extremely complex resource management problems. First, let's understand dangling references:
Example
let r;
{
let x = 5;
r = &x;
}
println!("r: {}", r);
}
This code will not pass the Rust compiler because the value referenced by r has already been dropped before it is used.

In the above diagram, the green range 'a represents r's lifetime, and the blue range 'b represents x's lifetime. Obviously, 'b is much shorter than 'a; a reference must be within the lifetime of the value to be valid.
We have always used String rather than &str in structs. Let's use an example to explain why:
Example
if s2.len() > s1.len() {
s2
} else {
s1
}
}
The longer function takes two string slices, s1 and s2, and returns the reference of the longer one. However, this code will not compile because the returned reference may be a dangling reference:
Example
let r;
{
let s1 = "rust";
let s2 = "ecmascript";
r = longer(s1, s2);
}
println!("{} is longer", r);
}
In this program, although a comparison has been made, by the time r is used, the source values s1 and s2 have already become invalid. Of course, we could move the use of r into the lifetime scope of s1 and s2 to prevent this error, but for the function, it cannot know what is happening outside itself. In order to ensure that the value it passes out is valid, it must follow the ownership principle to eliminate all dangers, so the longer function cannot compile.
Lifetime Annotation
Lifetime annotation is a way to describe the lifetime of references.
Although this cannot change the lifetime of references, it can declare that the lifetimes of two references are consistent in appropriate places.
A lifetime annotation starts with an apostrophe and is followed by a lowercase word:
&i32 // 常规引用 &'a i32 // 含有生命周期注释的引用 &'a mut i32 // 可变型含有生命周期注释的引用
Let's refactor the longer function using lifetime annotations:
Example
if s2.len() > s1.len() {
s2
} else {
s1
}
}
We need to use generic declarations to specify the lifetime names; then the lifetime of the function's return value will be consistent with the lifetimes of the two parameters, so when calling it we can write:
Example
let r;
{
let s1 = "rust";
let s2 = "ecmascript";
r = longer(s1, s2);
println!("{} is longer", r);
}
}
The combined output of the above two programs:
ecmascript is longer
Note:Don't forget the principle of automatic type inference.
Using String Slice References in Structs
This is the question left earlier; here is the answer:
Example
struct Str<'a> {
content: &'a str
}
let s = Str {
content: "string_slice"
};
println!("s.content = {}", s.content);
}
Output:
s.content = string_slice
If there is a method definition for the struct Str:
Example
fn get_content(&self) -> &str {
self.content
}
}
The return value here does not have a lifetime annotation, but adding one doesn't hurt. This is a historical issue: early Rust did not support automatic lifetime inference, and all lifetimes had to be strictly declared, but mainstream stable versions of Rust already support this feature.
Static Lifetime
There is a special lifetime annotation: 'static. The exact data type represented by all string constants enclosed in double quotes is &'static str; the lifetime denoted by 'static lasts from the start of program execution to the end of program execution.
Generics, Traits, and Lifetimes Working Together
Example
fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str
where T: Display
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}
This program comes from the Rust Bible (Rust Book). It is a program that uses generics, traits, and lifetime mechanisms at the same time. It is not mandatory; you can try it out, after all, you will need it sooner or later!
Other Extensions