TL;DR
- ヒープ上の値にも所有者がいて、所有者がドロップされるとヒープ上の値もドロップされる。
- ヒープ上の値の生存期間は、所有権の連鎖の終点で決まり、基本的にはスタック上の変数の生存期間と同じになる。
内容
項目14の節の 1 つ。
ヒープ上の値の所有者
ヒープ上の値には、Box::leak などで意図的にリークさせたものを除いて、所有者がいる。たとえば Box<T> は T の値をヒープに置くが、その所有者は Box<T> を持つ変数である。次のコードでは、Box<Item> の所有者は変数 b である。
{
let b: Box<Item> = Box::new(Item { contents: 42 });
}所有者がスコープを抜けてドロップされると、ヒープ上の値もドロップされる。つまり、ヒープ上のアイテムの生存期間は、スタック上の変数の生存期間と同じである。
所有権の連鎖
所有者自体がヒープ上にあることもある。その場合も、最終的に誰が所有しているか、つまり所有権の連鎖がどこで終わるかを知ることが大事である。
{
let b: Box<Item> = Box::new(Item { contents: 42 });
let bb: Box<Box<Item>> = Box::new(b); // b がヒープ上に移動する
} // bb がドロップされると Box<Item> も Item もドロップされるこのコードでは、Item は Box<Item> に、Box<Item> は Box<Box<Item>> に、Box<Box<Item>> はスタック上の変数 bb に所有されている。連鎖が終わるのはブロックが閉じたときである。
所有権の連鎖の終点は次のどちらかになる。
- ローカル変数または関数の引数。連鎖に含まれるすべてのアイテムの生存期間はスタック上の変数と同じになり、連鎖のすべてのアイテムがドロップされる
static変数。連鎖に含まれるすべてのアイテムの生存期間は'staticになり、どのアイテムもドロップされない('static ライフタイム)
以上から、ヒープ上のアイテムの生存期間は、基本的にスタックの生存期間と同じである。