首页 > 解决方案 > 引用相同/包含结构中的字段

问题描述

我创建了这个简单的示例来模拟程序中引用发生的情况。

struct Child {}

struct Parent<'a> {
    child: &'a Child
}

struct Family {
    child: Box<Child>,
    parents: Vec<Box<dyn Any>>
}

fn main() {
    let child = Box::new(Child {});
    let mut family = Family { child, parents: vec![] }; // child was moved to the family

    let parent = Box::new(Parent { child: &family.child }); // Parent accepts reference to family's child

    family.parents.push(parent); // Now parent was moved to the family.
    // So Family owns both: child and parent, 
    // so reference to the child in the parent will be correct during
    // lifetime of family
}

这段代码对我来说看起来是正确的,因为家庭同时拥有:孩子和父母,因此它们将同时被删除,并且父母可以安全地持有对孩子的引用。但是 rust 编译器不这么认为:

error[E0597]: `family.child` does not live long enough
   |
18 |     let parent = Box::new(Parent { child: &family.child }); // Parent accepts reference to family's child
   |                                           ^^^^^^^^^^^^^ borrowed value does not live long enough
19 | 
20 |     family.parents.push(parent); // Now
   |                         ------ cast requires that `family.child` is borrowed for `'static`
21 | }
   | - `family.child` dropped here while still borrowed

和框的使用dyn Any是有意的——它模拟了我的程序中发生的事情。

标签: rust

解决方案


You appear to have two unrelated issues:

1. Parent does not implement dyn Any

Despite the name, not every type implements the Any trait, as explained in the std::any documentation:

Most types implement Any. However, any type which contains a non-'static reference does not.

So your Parent struct cannot implement Any (unless it is restricted to only have 'static children). As you say the dyn Any comes from the rest of your program, it is difficult to advise a fix.

2. Storing a value and a reference to that value in the same struct

This has been asked before and there is a truly excellent answer.

The usual problem with self-referential structs is that they cannot be moved without invalidating the references.

However, in some cases we can move a self-referential struct safely, such as when the referred-to values are Boxed (as in your Family) provided that the boxed values are never moved. The linked-to answer covers this case and lists possible workarounds.


推荐阅读