rust の lifetime

まずは 1.0 alpha リリースおめでとうございます。

リリースしてドキュメント関係が差し替わって Book (旧 guide) に lifetime について乗るようになったぽい。

C++ はリファレンスによって NULL ポインタのデリファレンスを防げるようになったが、ダングリングリファレンスは依然として起こってしまう。 rust の lifetime の概念はこれを解決するためのものらしい。

lifetime は Book にあるように、 場合によって省略可能だが、コンパイラが決定できない場合ユーザーが明示的に指定する必要がある。 具体的には、以下のような場合。

fn f<'a> (x: &'a i32, y: &i32) -> &'a i32 {
    x
}

fn main() {
    let x = 1;
    let r: &i32;
    {
        let y = 2;
        r = f(&x, &y);
    }
}

この場合、f の仮引数の x と戻り値の lifetime が同一であると 'a として lifetime parameter を明示することで、 コンパイラに教えている。 この場合だと、x をリターンしているので、コンパイラでも検出できると思うが、以下のような場合を考えると、省略ルールから外れた場合は常に指定する必要があるというのは、デザインとして納得ができる。

fn f<'a> (x: &'a i32, y: &'a i32) -> &'a i32 {
    if *x == 0 {
        x
    } else {
        y
    }
}

ちなみに、最初の例で、f(&y, &x) とすると、y はスコープアウトするのに r に参照がわたってしまうので、コンパイルエラーになる。 こんな感じで rust は安全性を担保してるようだ。