Return 包含在需要生命周期参数的结构中的引用
Return reference wrapped in struct that requires lifetime parameters
如何 return 包装在结构中的引用以及需要什么样的生命周期注解?我很难提出我的确切问题,但以下示例说明了我正在尝试做的事情。我有一个结构 C
,其中包含对需要生命周期参数的结构 B
的引用。我想要 C
上的一个函数,它 return 是对 B
的引用,包裹在另一个用作接口的结构 Borrower
中。
编译时 returning Borrower
: 'cannot infer an appropriate lifetime for lifetime parameter 'b
due to conflicting requirements' 时出现错误。我该如何解决这个问题?我可以输入哪些生命周期参数?我觉得 'a
和 'b
都不是正确的生命周期。
struct C<'a, 'b> {
ref2: &'a mut B<'b>,
}
impl<'a, 'b> C<'a, 'b> {
fn get_borrower(&mut self) -> Borrower {
Borrower { ref3: self.ref2 }
}
}
struct Borrower<'a, 'b> {
ref3: &'a mut B<'b>,
}
impl<'a, 'b> Borrower<'a, 'b> {
fn print_and_add(&mut self) {
println!("ref is {}", self.ref3.ref1.i);
self.ref3.ref1.i += 1;
}
}
struct B<'a> {
ref1: &'a mut A,
}
struct A {
i: u32,
}
fn main() {
let mut a = A { i: 10 };
let mut b = B { ref1: &mut a };
let mut c = C { ref2: &mut b };
for _ in 0..10 {
let mut borrower = c.get_borrower();
borrower.print_and_add();
}
}
问题具体出在这个方法上:
impl<'a, 'b> C<'a, 'b> {
fn get_borrower(&mut self) -> Borrower {
Borrower { ref3: self.ref2 }
}
}
我们需要帮助编译器理解返回的 Borrower
中需要哪些生命周期参数,因为这里推断的生命周期是不正确的:生命周期省略 Borrower
可以扩展为 Borrower<'_, '_>
其中匿名生命周期都是 &mut self
的生命周期;如果我们称它为 's
,则等效签名为:
fn get_borrower<'s>(&'s mut self) -> Borrower<'s, 's> {
这显然是不对的,因为我们知道第二个生命期应该是'b
,正如B<'b>
类型的字段ref2
直接描述的那样。使用以下签名(并修复不相关的错误后),the code compiles successfully:
fn get_borrower(&mut self) -> Borrower<'_, 'b> {
有趣的部分在第一个参数中。人们可能倾向于假设我们希望它是 'a
而不是 's
,但这仍然会导致生命周期冲突:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:7:9
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'s` as defined on the method body at 6:21...
--> src/main.rs:6:21
|
6 | fn get_borrower<'s>(&'s mut self) -> Borrower<'a, 'b> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:7:26
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 5:6...
--> src/main.rs:5:6
|
5 | impl<'a, 'b> C<'a, 'b> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:7:9
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Borrower<'a, 'b>`
found `Borrower<'_, '_>`
这是因为我们在对 self 的 mutable 引用后面检索 ref2
,并且它有自己的生命周期。我们不能强行将它移出 self
来实现生命周期 'a
,也不能传递一个 &'s mut &'a mut B<'b>
。因此,返回 Borrower<'s, 'b>
是正确的做法:因为隐含 'a: 's
('a
比 's
长),此生命周期中的协方差将使该方法能够将可变引用 &'a mut B<'b>
缩小到其子类型 &'s mut B<'b>
.
----------
| 'a |
| ------ |
|| 's | ---> Borrower<'s, 'b>
|| | |
| ------ |
----------
另请参阅:
- mutably borrow fields from a mutably borrowed struct
如何 return 包装在结构中的引用以及需要什么样的生命周期注解?我很难提出我的确切问题,但以下示例说明了我正在尝试做的事情。我有一个结构 C
,其中包含对需要生命周期参数的结构 B
的引用。我想要 C
上的一个函数,它 return 是对 B
的引用,包裹在另一个用作接口的结构 Borrower
中。
编译时 returning Borrower
: 'cannot infer an appropriate lifetime for lifetime parameter 'b
due to conflicting requirements' 时出现错误。我该如何解决这个问题?我可以输入哪些生命周期参数?我觉得 'a
和 'b
都不是正确的生命周期。
struct C<'a, 'b> {
ref2: &'a mut B<'b>,
}
impl<'a, 'b> C<'a, 'b> {
fn get_borrower(&mut self) -> Borrower {
Borrower { ref3: self.ref2 }
}
}
struct Borrower<'a, 'b> {
ref3: &'a mut B<'b>,
}
impl<'a, 'b> Borrower<'a, 'b> {
fn print_and_add(&mut self) {
println!("ref is {}", self.ref3.ref1.i);
self.ref3.ref1.i += 1;
}
}
struct B<'a> {
ref1: &'a mut A,
}
struct A {
i: u32,
}
fn main() {
let mut a = A { i: 10 };
let mut b = B { ref1: &mut a };
let mut c = C { ref2: &mut b };
for _ in 0..10 {
let mut borrower = c.get_borrower();
borrower.print_and_add();
}
}
问题具体出在这个方法上:
impl<'a, 'b> C<'a, 'b> {
fn get_borrower(&mut self) -> Borrower {
Borrower { ref3: self.ref2 }
}
}
我们需要帮助编译器理解返回的 Borrower
中需要哪些生命周期参数,因为这里推断的生命周期是不正确的:生命周期省略 Borrower
可以扩展为 Borrower<'_, '_>
其中匿名生命周期都是 &mut self
的生命周期;如果我们称它为 's
,则等效签名为:
fn get_borrower<'s>(&'s mut self) -> Borrower<'s, 's> {
这显然是不对的,因为我们知道第二个生命期应该是'b
,正如B<'b>
类型的字段ref2
直接描述的那样。使用以下签名(并修复不相关的错误后),the code compiles successfully:
fn get_borrower(&mut self) -> Borrower<'_, 'b> {
有趣的部分在第一个参数中。人们可能倾向于假设我们希望它是 'a
而不是 's
,但这仍然会导致生命周期冲突:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/main.rs:7:9
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'s` as defined on the method body at 6:21...
--> src/main.rs:6:21
|
6 | fn get_borrower<'s>(&'s mut self) -> Borrower<'a, 'b> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:7:26
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 5:6...
--> src/main.rs:5:6
|
5 | impl<'a, 'b> C<'a, 'b> {
| ^^
note: ...so that the expression is assignable
--> src/main.rs:7:9
|
7 | Borrower { ref3: self.ref2 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Borrower<'a, 'b>`
found `Borrower<'_, '_>`
这是因为我们在对 self 的 mutable 引用后面检索 ref2
,并且它有自己的生命周期。我们不能强行将它移出 self
来实现生命周期 'a
,也不能传递一个 &'s mut &'a mut B<'b>
。因此,返回 Borrower<'s, 'b>
是正确的做法:因为隐含 'a: 's
('a
比 's
长),此生命周期中的协方差将使该方法能够将可变引用 &'a mut B<'b>
缩小到其子类型 &'s mut B<'b>
.
----------
| 'a |
| ------ |
|| 's | ---> Borrower<'s, 'b>
|| | |
| ------ |
----------
另请参阅:
- mutably borrow fields from a mutably borrowed struct