2017-07-26 17 views
3
を住んでいない

次のコードはコンパイルされません:寿命は十分な長

use std::borrow::Borrow; 

struct Inner<'a> { 
    v: Vec<&'a u8>, 
} 

struct Foo<'a> { 
    inner: Inner<'a>, 
    derp: Box<u8>, 
} 

impl<'a> Foo<'a> { 
    fn new() -> Foo<'a> { 
     let mut e = Foo { 
      inner: Inner { v: vec![] }, 
      derp: Box::new(128), 
     }; 
     e.inner.v.push(&*e.derp); 

     return e; 
    } 

    fn derp(&mut self) { 
     println!("{:?}", self.inner.v); 
    } 
} 

fn main() { 
    let mut f = Foo::new(); 

    f.derp(); 
} 

を私は次のエラーを取得する:

error[E0597]: `*e.derp` does not live long enough 
    --> src/main.rs:18:25 
    | 
18 |   e.inner.v.push(&*e.derp); 
    |       ^^^^^^^ does not live long enough 
... 
21 |  } 
    |  - borrowed value only lives until here 
    | 
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 12:1... 
    --> src/main.rs:12:1 
    | 
12 |/impl<'a> Foo<'a> { 
13 | |  fn new() -> Foo<'a> { 
14 | |   let mut e = Foo { 
15 | |    inner: Inner { v: vec![] }, 
... | 
25 | |  } 
26 | | } 
    | |_^ 

私は内部の値だと思いますボックスは、Fooのメンバーであるため、生涯正確に'aの長さの間存続します。

新しい機能の最後にFooの移動が混乱していたかどうか、私は疑問に思ったので、derpで追加しようとするとします。

error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements 
    --> main.rs:20:27 
    | 
20 |   self.inner.v.push(& *self.derp); 
    |       ^^^^^^^^^^ 

これは、コンパイル時にボックス化された値がどのように存続しているかを示すものではありません。

答えて

3

I think though that the value inside of the box does live for as long as 'a since it is a member of Foo which has exactly that lifetime.

古いボックスが削除され、その中に価値の寿命が終了した時点でderpメンバーに新しいボックスを割り当てることが可能です。

あなたがしようとしていることは安全では不可能だと思うRust:構造体メンバ間の相互参照はサポートされていません。これは定期的に質問として出ますが、言語では利用できません。

あなたはおそらくRefCellとの組み合わせで、この問題を回避するためにRcを使用することができます。

+0

ああ、わかります。それは理にかなっていると思います。私はこれが可能であるのを止めて、箱を生涯にわたって生き残らせるような方法があるのだろうかと思います。 –

関連する問題