代码之家  ›  专栏  ›  技术社区  ›  Bob Bobbio

引用盒装值的生命周期不够长

  •  3
  • Bob Bobbio  · 技术社区  · 7 年前

    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 | | }
       | |_^
    

    '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);
       |                           ^^^^^^^^^^
    

    这没有告诉我编译器认为装箱值的生存期。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Shepmaster Tim Diekmann    7 年前

    可以将新框分配给 derp 成员,此时旧框将被丢弃,其中值的生存期结束。

    我认为在safe-Rust中,您试图做的是不可能的:不支持结构成员之间的交叉引用。这是一个经常出现的问题,但它只是在语言中不可用。

    Rc 为了解决这个问题,可能需要结合 RefCell .