Log*_*Wlv 1 reference lifetime rust borrow-checker borrowing
我想我部分理解了生命周期的概念,但我在递归类型定义中遇到了问题:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器说:
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<'_>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
那个怎么样?在我的理解中,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);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然上面的编译在实践中你会发现它非常严格并且难以使用,如果可以克隆Persons ,那么你将更容易使用这个结构:
struct Person {
children: Vec<Person>,
// other fields
}
Run Code Online (Sandbox Code Playgroud)
如果您需要Person在多个children向量之间共享s同时能够改变它们,您应该使用:
struct Person {
children: Vec<Rc<RefCell<Person>>>,
// other fields
}
Run Code Online (Sandbox Code Playgroud)
如果您将所有Persons存储HashMap<String, Person>在键唯一且不可变的a中,您还可以children像这样维护每个向量:
struct Person {
children: Vec<String>, // keys for HashMap<String, Person>
// other fields
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |