递归类型-生命周期问题
我想我部分理解了生命周期的概念,但我在递归类型定义中遇到了问题:
struct Person<'a> {
name: String,
children: Vec<&'a mut Person<'a>>,
birth: String,
death: String,
religion: String,
genre: String,
}
impl Person<'_> {
fn add_children(&'_ mut self, p: &'_ mut Person<'_>) {
self.children.push(p);
}
}
编译器说:
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/lib.rs:12:28
|
12 | self.children.push(p);
| ^
|
note: ...the reference is valid for the lifetime `'_` as defined on the impl at 10:13...
--> src/lib.rs:10:13
|
10 | impl Person<'_> {
| ^^
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 11:5
--> src/lib.rs:11:5
|
11 | fn add_children(&'_ mut self, p: &'_ mut Person<'_>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> src/lib.rs:12:28
|
12 | self.children.push(p);
| ^ lifetime mismatch
|
= note: expected mutable reference `&mut Person<'_>`
found mutable reference `&mut Person<'_>`
note: the anonymous lifetime #3 defined on the method body at 11:5...
--> src/lib.rs:11:5
|
11 | fn add_children(&'_ mut self, p: &'_ mut Person<'_>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 10:13
--> src/lib.rs:10:13
|
10 | impl Person<'_> {
| ^^
error[E0308]: mismatched types
--> src/lib.rs:12:28
|
12 | self.children.push(p);
| ^ lifetime mismatch
|
= note: expected mutable reference `&mut Person<'_>`
found mutable reference `&mut Person<'_>`
note: the lifetime `'_` as defined on the impl at 10:13...
--> src/lib.rs:10:13
|
10 | impl Person<'_> {
| ^^
note: ...does not necessarily outlive the anonymous lifetime #3 defined on the method body at 11:5
--> src/lib.rs:11:5
|
11 | fn add_children(&'_ mut self, p: &'_ mut Person<'_>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
那个怎么样?在我的理解中,self
和p
拥有一样的一生。
我希望它是一个,Vec<&mut Person>
因为我有一个HashMap<String, Person>
每个人都将其孩子初始化为Vec::new()
. 我想传递对 的引用,Vec
以便在更新子项时不会复制整个人的数据。
回答
'_
告诉编译器为您推断生命周期,但在这种情况下,它正在推断一堆不同的匿名生命周期。由于的生命周期Person
直接依赖于它的生命周期,children
你应该在你的实现中明确说明,一旦你这样做,它就会编译:
struct Person<'a> {
name: String,
children: Vec<&'a mut Person<'a>>,
birth: String,
death: String,
religion: String,
genre: String,
}
impl<'a> Person<'a> {
fn add_children(&mut self, p: &'a mut Person<'a>) {
self.children.push(p);
}
}
操场
虽然上面的编译在实践中你会发现它非常严格并且难以使用,如果可以克隆Person
s ,那么你将更容易使用这个结构:
struct Person {
children: Vec<Person>,
// other fields
}
如果您需要Person
在多个children
向量之间共享s同时能够改变它们,您应该使用:
struct Person {
children: Vec<Rc<RefCell<Person>>>,
// other fields
}
如果您将所有Person
s存储HashMap<String, Person>
在键唯一且不可变的a中,您还可以children
像这样维护每个向量:
struct Person {
children: Vec<String>, // keys for HashMap<String, Person>
// other fields
}