web-dev-qa-db-ja.com

構造体のBox <T>に「明示的なライフタイム境界が必要」なのはなぜですか?

編集者注: RFC 599 が実装された後、このコードは同じエラーを生成しなくなりましたが、回答で説明されている概念は引き続き有効です。

私はこのコードをコンパイルしようとしています:

trait A {
    fn f(&self);
}

struct S {
    a: Box<A>,
}

そして私はこのエラーを受け取ります:

a.rs:6:13: 6:14 error: explicit lifetime bound required
a.rs:6     a: Box<A>,

が欲しいです S.aAのインスタンスを所有し、その存続期間がここでどのように適切であるかがわかりません。コンパイラを幸せにするために何をする必要がありますか?

私のRustバージョン:

rustc --version
rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000)
21
Eugene Zemtsov

ここでの問題は、参照にもトレイトを実装できることです。そのため、Boxに必要な有効期間を指定しないと、そこに何かが格納される可能性があります。

あなたはこれで寿命要件について見ることができます rfc

したがって、考えられる解決策の1つは、ライフタイムをバインドしてSend(IをSに入れる)です。

trait A {
    fn f(&self);
}

struct I;

impl A for I {
    fn f(&self) {
        println!("A for I")
    }
}

struct S {
    a: Box<A + Send>
}

fn main() {
    let s = S {
        a: box I
    };
    s.a.f();
}

もう1つは、有効期間を'aに設定することです(参照&IまたはIをSに設定できます)。

trait A {
    fn f(&self);
}

struct I;

impl A for I {
    fn f(&self) {
        println!("A for I")
    }
}

impl <'a> A for &'a I {
    fn f(&self) {
        println!("A for &I")
    }
}

struct S<'a> {
    a: Box<A + 'a>
}

fn main() {
    let s = S {
        a: box &I
    };
    s.a.f();
}

これはより一般的であり、参照と所有データ(Sendの有効期間が'staticの種類)の両方を格納できますが、タイプが使用されるすべての場所で有効期間パラメーターが必要であることに注意してください。

19
Arjan