生命周期

生命周期是编译器(更具体地说,是其借用检查器)用来确保所有借用都有效的构造。具体来说,一个变量的生命周期从它被创建时开始,到它被销毁时结束。虽然生命周期和作用域经常被一起提及,但它们并不相同。

例如,当我们通过&借用一个变量时。这个借用的生命周期由它被声明的位置决定。因此,只要它在出借者被销毁之前结束,借用就是有效的。然而,借用的作用域由引用的使用位置决定。

在下面的示例以及本节的其余部分中,我们将看到生命周期如何与作用域相关,以及两者之间的区别。

// 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. ─────────────────────────────────────┘

请注意,没有名称或类型被分配用来标记生命周期。这限制了我们将如何使用生命周期,我们将会看到。