Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
ライフタイム('a)
ライフタイム(lifetime)は参照の有効期間を示すアノテーションで、コンパイラがダングリング参照を検出するために使用します。関数や構造体で複数の参照の有効期間を関連付けるときに明示的に記述します。
構文
// 関数シグネチャでのライフタイムアノテーション
fn 関数名<'a>(x: &'a str, y: &'a str) -> &'a str { ... }
// 構造体フィールドのライフタイム
struct 構造体名<'a> {
field: &'a str,
}
// 静的ライフタイム(プログラム全体で有効)
let s: &'static str = "hello";
ライフタイム記法一覧
| 記法 | 概要 |
|---|---|
| 'a | ライフタイムパラメータです。任意の名前を使えますが慣習的に'aから始めます。 |
| &'a T | ライフタイム'aを持つ型Tへの不変参照です。 |
| &'a mut T | ライフタイム'aを持つ型Tへの可変参照です。 |
| 'static | プログラムの実行中ずっと有効な特別なライフタイムです。文字列リテラルが該当します。 |
サンプルコード
// 2つの文字列スライスのうち長い方を返します。
// 戻り値は引数と同じライフタイムを持ちます。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
// ライフタイムを持つ構造体
struct Important<'a> {
content: &'a str,
}
impl<'a> Important<'a> {
fn display(&self) {
println!("{}", self.content);
}
}
fn main() {
let s1 = String::from("long string");
let result;
{
let s2 = String::from("xyz");
result = longest(s1.as_str(), s2.as_str());
println!("最長: {}", result); // s2が有効な間だけresultを使えます。
}
// 静的ライフタイム
let s: &'static str = "プログラム終了まで有効です";
println!("{}", s);
let novel = String::from("物語が始まります。次の章では...");
let first_sentence;
{
let i = Important {
content: novel.split('。').next().unwrap(),
};
i.display();
first_sentence = i.content;
}
println!("{}", first_sentence);
}
概要
ライフタイムアノテーションは参照の有効期間を変えるものではなく、コンパイラに複数の参照の有効期間の関係を伝えるためのものです。多くの場合、コンパイラが「ライフタイム省略規則(elision rules)」により自動推論するため、明示的な記述が不要なこともあります。
ライフタイムの不一致はコンパイルエラーになります。関数が参照を返す場合、戻り値のライフタイムはいずれかの引数のライフタイムと関連付ける必要があります。
参照の基本については借用 / 参照(&)を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。