生命周期

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

以我们通过 & 借用变量为例。借用的生命周期由其声明的位置决定。因此,只要借用在出借方销毁之前结束,它就是有效的。但是,借用的作用域由引用的使用位置决定。

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

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

请注意,没有为标签生命周期分配名称或类型。正如我们将看到的,这限制了生命周期的使用方式。