Beginning Rustは言語仕様を単に羅列するのではなく、なぜそのような仕様にする必要があるかを丁寧に説明していますが、ライフサイクル指定でもそれは同じことが言えます。
そもそも関数が返すことができる参照(リファレンス)とは、以下の二つのうちのどちらかだと、
① 静的オブジェクトの借用:以下のstr関数
② 引数の借用:以下のf関数
それ以外の関数の引数オブジェクト、関数内のローカル変数オブジェクト、関数内の一時的オブジェクトは関数から戻る時に破棄されるから参照にはなり得ない、したがってライフタイム指定が必要なケース(本来は関数の戻り時点で破棄されるオブジェクトを、戻り値の参照が破棄されるまでライフタイムを延命と同義)もある程度限定的ということになる。コードとしてライフタイム表記はスッキリ感がないし、
/* It prints:
Static object
13 12*/
fn main() {
// borrowing of the static object
fn str<'a>() -> &'a str {
"Static object"
}
println!("{}", str());
// borrowing of the augments
// in this case x and y need to have different life time
fn f<'a, 'b>(x: &'a i32, y: &'b i32) -> (&'a i32, bool, &'b i32) {
(x, true, y)
}
let i1 = 12;
let i2;
{
let j1 = 13;
let j2;
let r = f(&i1, &j1);
i2 = r.0;
j2 = r.2;
print!("{} ", *j2);
}
print!("{}", *i2);
}
関数fで複数のライフタイムが必要な理由は、関数fを展開してみれば理由がわかる、つまり{}の外側にあるi1/i2と内側にあるj1/j2では本質的なライフタイムに差があるのだから、それを一律なライフタイムで規定しようとしても不可能だということを言っているだけ。
admin