境界
ジェネリック型に境界を与え、特定のトレイトを実装していることを保証できるのと同様、ライフタイム(それ自身ジェネリック型)にも境界を与えることができます。:
は、ここでは多少異なる意味を持ちますが+
は同じです。以下の構文の意味をチェックしてください。
T: 'a
:T
内の 全ての 参照は'a
よりも長生きでなくてはなりません。T: Trait + 'a
:上に加えてT
はTrait
という名のトレイトを実装してなくてはなりません。
上記の構文を実際に動く例で見ていきましょう。where
キーワードの後に注目してください。
use std::fmt::Debug; // ライフタイムを紐付けるトレイト #[derive(Debug)] struct Ref<'a, T: 'a>(&'a T); // `Ref` contains a reference to a generic type `T` that has // some lifetime `'a` unknown by `Ref`. `T` is bounded such that any // *references* in `T` must outlive `'a`. Additionally, the lifetime // of `Ref` may not exceed `'a`. // `Debug`トレイトを利用して出力を行うジェネリック関数 fn print<T>(t: T) where T: Debug { println!("`print`: t is {:?}", t); } // `Debug`を実装している`T`への参照を取りません。`T`への *参照* は // 必ず`'a`よりも長生きでなくてはなりません。さらに、`'a`は // 関数自体よりも長生きでなくてはなりません。 fn print_ref<'a, T>(t: &'a T) where T: Debug + 'a { println!("`print_ref`: t is {:?}", t); } fn main() { let x = 7; let ref_x = Ref(&x); print_ref(&ref_x); print(ref_x); }