gpt4 book ai didi

rust - 递归类型-生命周期问题

转载 作者:行者123 更新时间:2023-12-03 11:32:31 35 4
gpt4 key购买 nike

我想我部分理解了生命周期概念,但是在递归类型定义中存在一个问题:

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>,每个人的 child 都被初始化为 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);
}
}
playground
尽管上面的编译在实践中会发现它具有难以置信的局限性并且很难使用,但是如果可以克隆 Person的话,使用该结构的时间会短得多:
struct Person {
children: Vec<Person>,
// other fields
}
如果您需要在多个 Person向量之间共享 children,同时又能够对其进行突变,则应该使用:
struct Person {
children: Vec<Rc<RefCell<Person>>>,
// other fields
}
如果将所有 Person存储在键是唯一且不可变的 HashMap<String, Person>中,则还可以像这样维护每个 children向量:
struct Person {
children: Vec<String>, // keys for HashMap<String, Person>
// other fields
}

关于rust - 递归类型-生命周期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65205376/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com