Rust lifecycle mechanism is a resource management mechanism as important as ownership mechanism.
The reason why this concept is introduced is to deal with the problem of resource management in complex type systems.
Reference is an indispensable mechanism when dealing with complex types, after all, complex type data cannot be easily copied and calculated by the processor.
But references often lead to extremely complex resource management problems,so first take a look at overhanging references: This code will not pass the Rust compiler because the value referenced by r has been released before it is used. The green range’an in the figure above represents the life cycle of r and the blue range’b represents the life cycle of x. Obviously,’b is much smaller than’a, and the reference must be within the lifetime of the value to be valid. We’ve always used it in structures. Although this program has been compared, the source values S1 and S2 are invalid when r is used. Of course, we can move the use of r to the life cycle of S1 and S2 to prevent this error from happening, but for the function, it does not know what is going on outside itself. In order to ensure that the value it passes out is normal, it must choose the ownership principle to eliminate all dangers, so the Lifecycle annotations are a way to describe reference lifecycles. Although this does not change the lifecycle of the reference, you can declare that the lifecycle of the two references is the same in the appropriate place. Lifecycle comments begin with single quotation marks, followed by a lowercase word: Let’s transform with lifecycle annotations We need to standardize the name of the life cycle with a generic declaration, and then the life cycle of the return value of the function will be the same as the life cycle of the two parameters, so you can write this when calling: The running result of the combination of the above two programs: Note: don’t forget the principle of automatic type determination. This is the question left before, and here is the answer: Running result: If the structure The return value here has no lifecycle comments, but it doesn’t hurt to add it. This is a historical issue. Early Rust did not support automatic lifecycle judgment, and all lifecycles must be strictly declared, but mainstream stable versions of Rust already support this feature. The lifecycle annotation has a special feature: This program comes from the Rust Bible, is a program that uses generics, features, and life cycle mechanisms at the same time. It is not required, itcan be experienced, after all, it can be used sooner or later! 7.18.1. Example #
{
let r;
{
let x = 5;
r = &x;
}
println!("r: {}", r);
}

String
without having to
&str
, let’s use a case to explain why: 7.18.2. Example #
fn longer(s1: &str, s2: &str) -> &str {
if s2.len() > s1.len() {
s2
} else {
s1
}
}
longer
function takes the longer of the two string slices S1 and S2 and returns its reference value. But only this code will not be compiled because the return value reference may return an expired reference: 7.18.3. Example #
fn main() {
let r;
{
let s1 = "rust";
let s2 = "ecmascript";
r = longer(s1, s2);
}
println!("{} is longer", r);
}
longer
function cannot be compiled.Lifecycle comment #
&I32//General reference
&'a i32//References containing lifecycle annotations
&'a mut i32//Variable references with lifecycle annotations
longer
function: 7.18.4. Example #
fn longer<'a>(s1: &'a str, s2: &'a str) -> &'a str {
if s2.len() > s1.len() {
s2
} else {
s1
}
}
7.18.5. Example #
fn main() {
let r;
{
let s1 = "rust";
let s2 = "ecmascript";
r = longer(s1, s2);
println!("{} is longer", r);
}
}
ecmascript is longer
Using string slice references in structures #
7.18.6. Example #
fn main() {
struct Str<'a> {
content: &'a str
}
let s = Str {
content: "string_slice"
};
println!("s.content = {}", s.content);
}
s.content = string_slice
Str
has methods to define: 7.18.7. Example #
impl<'a> Str<'a> {
fn get_content(&self) -> &str {
self.content
}
}
Static life cycle #
'static
. The exact data type represented by all string constants enclosed in double quotation marks is
&'static
str
, and the lifecycle represented by
'static
is from the start of program operation to the end of program operation.Generics, features, and lifecycle work together #
7.18.8. Example #
use std::fmt::Display;
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
}
}