Lifetimes
Alifetime is a construct the compiler (or more specifically, itsborrowchecker) uses to ensure all borrows are valid. Specifically, a variable'slifetime begins when it is created and ends when it is destroyed. Whilelifetimes and scopes are often referred to together, they are not the same.
Take, for example, the case where we borrow a variable via&. Theborrow has a lifetime that is determined by where it is declared. As a result,the borrow is valid as long as it ends before the lender is destroyed. However,the scope of the borrow is determined by where the reference is used.
In the following example and in the rest of this section, we will see howlifetimes relate to scopes, as well as how the two differ.
// Lifetimes are annotated below with lines denoting the creation// and destruction of each variable.// `i` has the longest lifetime because its scope entirely encloses// both `borrow1` and `borrow2`. The duration of `borrow1` compared// to `borrow2` is irrelevant since they are disjoint.fn main() { let i = 3; // Lifetime for `i` starts. ────────────────┐ // │ { // │ let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ // ││ println!("borrow1: {}", borrow1); // ││ } // `borrow1` ends. ─────────────────────────────────┘│ // │ // │ { // │ let borrow2 = &i; // `borrow2` lifetime starts. ──┐│ // ││ println!("borrow2: {}", borrow2); // ││ } // `borrow2` ends. ─────────────────────────────────┘│ // │} // Lifetime ends. ─────────────────────────────────────┘
Note that no names or types are assigned to label lifetimes.This restricts how lifetimes will be able to be used as we will see.