rust - 引用相同/包含结构中的字段
问题描述
我创建了这个简单的示例来模拟程序中引用发生的情况。
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
是有意的——它模拟了我的程序中发生的事情。
解决方案
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 Box
ed (as in your Family
) provided that the boxed values are never moved. The linked-to answer covers this case and lists possible workarounds.
推荐阅读
- python - 将 Spark DataFrame 写入 Redis 时如何提高速度?
- javascript - each() 函数不在 DOM 中,delegeta 问题 jquery
- java - 在java中将矩阵的外环逆时针旋转k个元素,顺时针旋转内环k个元素
- swift - 检查并将文档添加到 Firestore 数据库 (swift)
- javascript - 从模式数组中删除子文档
- scala - Scala,在列表中找到最大的列表
- javascript - ajax提交多个变量
- python - 从索引、值对填充一个 numpy 数组而不进行迭代
- swift - How can I make a variable take only one of certain values in Swift 5
- python - 使用 OpenCV (putText) 设置文本宽度