rust lifetime.
fn main() {
let x = "hi"; // lifetime a.
let e; // e should have a lifetime a.
{
let y = "you"; // lifetime b.
e = check(&x, &y); // here we returned lifetime b.
} // lifetime b ends, y is dropped.
println!("{}", e)
} // end of lifetime a.
// The compiler doesn't know which is small lifetime,
// which is big lifetime, we can use `where 'a: 'b` to tell
// the compiler that lifetime a live longer than lifetime b.
fn check<'a, 'b>(s: &'a str, b: &'b str) -> &'b where 'a: 'b {
println!("{}", b);
// the return signature `-> &'b` means we are returning something to
// a variable with lifetime b.
// we returned a content with lifetime a which is bigger than lifetime
// b. This is ok.
return s;
}
// BAD !!!!
fn check<'a, 'b>(s: &'a str, b: &'b str) -> &'a where 'a: 'b {
// now we returned a content with lifetime b, which is smaller than lifetime a.
// and the function's return value will be assign to some variable that has lifetime a.
// ---------
// {
// lifetime a
//
// {
// lifetime b
// } // b is dropped, will be not accessable for example.
// Since you assign b to a variable with lifetime a,
// If I use the variable here, it will cause an error, the variable reference to a content
// that is dropped at the ends of lifetime b.
// } // end of lifetime a.
// ---------
return b;
}
// lifetime == scope
let x = 3; // scope a
{
let b = 4; // scope b
}
let a = &b
, the lifetime of a must be small than lifetime of b, otherwise it will be invalid when b ends before a.
That means we can only assign a smaller lifetime variable to a bigger lifetime variable. small <> big
, not big <> small
.
It is same for the return of function. if the return of function have lifetime big
, but the content of the return have lifetime
small
, than there is a chance that the content will be dropped before lifetime big
end, that should not be happend.