明示的アノテーション
借用チェッカーは参照がどれだけの間有効かを決定するために、明示的なアノテーションを使用します。ライフタイムが省略1されなかった場合、Rustは参照のライフタイムがどのようなものであるか、明示的なアノテーションを必要とします。
foo<'a>
// `foo`は`'a`というライフタイムパラメータを持ちます。
クロージャと同様、ライフタイムの使用はジェネリクスを必要とします。もう少し詳しく言うと、この書き方は「fooのライフタイムは'aのそれを超えることはない。」ということを示しており、型を明示した場合'aは&'a Tとなるということです。
ライフタイムが複数ある場合も、同じような構文になります。
foo<'a, 'b>
// `foo`は`'a`と`'b`というライフタイムパラメータを持ちます。
この場合は、fooのライフタイムは'a、'bの いずれよりも 長くなってはなりません。
以下はライフタイムを明示的に書く場合の例です。
// `print_refs`は`i32`への参照を2つとり、それぞれ`'a`と`'b`という
// ライフタイムを持ちます。これらのライフタイムは最短でも`print_refs`
// 関数と同じになります。
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
println!("x is {} and y is {}", x, y);
}
// 引数を取らないがライフタイムパラメータ`'a`を持つ関数
fn failed_borrow<'a>() {
let _x = 12;
// エラー:`_x`の寿命が短すぎる。
let _y: &'a i32 = &_x;
// Attempting to use the lifetime `'a` as an explicit type annotation
// inside the function will fail because the lifetime of `&_x` is shorter
// than that of `_y`. A short lifetime cannot be coerced into a longer one.
}
fn main() {
// 下で借用するための変数を作成。
let (four, nine) = (4, 9);
// 2つの変数の借用(`&`)が関数に渡されます。
print_refs(&four, &nine);
// Any input which is borrowed must outlive the borrower.
// In other words, the lifetime of `four` and `nine` must
// be longer than that of `print_refs`.
failed_borrow();
// `failed_borrow` contains no references to force `'a` to be
// longer than the lifetime of the function, but `'a` is longer.
// Because the lifetime is never constrained, it defaults to `'static`.
}