14.4 ライフタイム
ライフタイムはコンパイラ(借用チェッカーと呼ばれる場合もあります)が、全ての借用に問題がないことを確認するために使用する仕組みです。正確にいうと、変数のライフタイムは作成時に開始し、破棄された時に終了します。ライフタイムとスコープは同時に語られることが多いですが、同じものではありません。
例として&
を用いて変数を借用する場合をあげましょう。借用のライフタイムは宣言時に決定し、そこから貸し手が破棄されるまで続きます。しかしながら、借用のスコープは参照が使われる際に決定します。
以下の例からこのセクションの残りでは、ライフタイムとスコープの関係、そしてそれらがいかに異なるものであるかを見ていきます。
// 以下では、変数の作成から破棄までのライフタイムを線で示しています。
// `i`は最長のライフタイムを持ち、そのスコープは`borrow1`および`borrow2`
// のスコープを完全に包含します。`borrow1`と`borrow2`の存続期間は一切重なりません。
fn main() {
let i = 3; // `i`のライフタイムが開始 ────────────────┐
// │
{ // │
let borrow1 = &i; // `borrow1`のライフタイム開始 ──┐│
// ││
println!("borrow1: {}", borrow1); // ││
} // `borrow1`が終了 ──────────────────────────────────┘│
// │
// │
{ // │
let borrow2 = &i; // `borrow2`のライフタイム開始 ──┐│
// ││
println!("borrow2: {}", borrow2); // ││
} // `borrow2`が終了 ─────────────────────────────────┘│
// │
} // ライフタイムの終了 ─────────────────────────────────────┘
ここで、一切の名前や型がライフタイムにアサインされていないことに注意しましょう。これにより、ライフタイムの使われ方がこれから見ていくようなやり方に制限されます。