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

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();
}

I get the following error:

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 的成员,而 Foo 恰好有这个生命周期。

我想知道在新函数结尾处移动 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个回答

3
我认为盒子中的值只要' a 存在,就会存活,因为它是具有该生命周期的 Foo 的成员。
可以对 derp 成员分配一个新的盒子,在这一点上旧的盒子将被丢弃,其中的值的生命周期也就结束了。
我认为在安全的 Rust 中你所尝试做的是不可能的: 结构成员之间的交叉引用不受支持。这经常出现作为一个问题,但它在语言中不可用。
如下链接: - 如何初始化相互引用的结构体字段 - 为什么不能在同一结构体中存储值和对该值的引用 你可以使用Rc来解决这个问题,也许结合RefCell一起使用。

啊,我明白了。我想这是有道理的。不知道是否有任何方法可以阻止这种情况发生,并强制该框在'a'的整个生命周期内存在。 - Bob Bobbio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接