生命周期
生命周期是编译器(更具体地说是其借用检查器)用来确保所有借用都有效的一种机制。具体来说,变量的生命周期从创建时开始,到销毁时结束。尽管生命周期和作用域经常被一同提及,但它们并不完全相同。
举个例子,当我们通过 &
借用一个变量时,这个借用的生命周期由其声明位置决定。因此,只要借用在出借者被销毁之前结束,它就是有效的。然而,借用的作用域则由引用使用的位置决定。
在接下来的例子和本节的其余部分中,我们将看到生命周期如何与作用域相关联,以及两者之间的区别。
// 下面用线条标注了每个变量的创建和销毁,以表示生命周期。 // `i` 的生命周期最长,因为它的作用域完全包含了 `borrow1` 和 `borrow2`。 // `borrow1` 相对于 `borrow2` 的持续时间是无关紧要的,因为它们是不相交的。 // (译注:为避免中文的宽度显示问题,下面注释没有翻译) 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. ─────────────────────────────────────┘
请注意,生命周期标签没有被赋予名称或类型。这限制了生命周期的使用方式,我们将在后面看到这一点。