递归类型-生命周期问题

我想我部分理解了生命周期的概念,但我在递归类型定义中遇到了问题:

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<'_>) {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

那个怎么样?在我的理解中,selfp拥有一样的一生。

我希望它是一个,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);
    }
}

操场

虽然上面的编译在实践中你会发现它非常严格并且难以使用,如果可以克隆Persons ,那么你将更容易使用这个结构:

struct Person {
    children: Vec<Person>,
    // other fields
}

如果您需要Person在多个children向量之间共享s同时能够改变它们,您应该使用:

struct Person {
    children: Vec<Rc<RefCell<Person>>>,
    // other fields
}

如果您将所有Persons存储HashMap<String, Person>在键唯一且不可变的a中,您还可以children像这样维护每个向量:

struct Person {
    children: Vec<String>, // keys for HashMap<String, Person>
    // other fields
}


以上是递归类型-生命周期问题的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>