[英]Return reference wrapped in struct that requires lifetime parameters
How can I return a reference wrapped in a struct and what lifetime annotation is required?如何返回包装在结构中的引用以及需要什么生命周期注释? I am having a tough time formulating my exact question, but the following example illustrates what I am trying to do.我很难制定我的确切问题,但以下示例说明了我正在尝试做的事情。 I have a struct C
that contains a reference to a struct B
that requires lifetime parameters.我有一个结构C
,其中包含对需要生命周期参数的结构B
的引用。 I want a function on C
that returns the reference to B
wrapped in another struct Borrower
that functions as an interface.我想要一个C
上的函数,该函数返回对B
的引用,该B
包含在另一个用作接口的 struct Borrower
中。
When compiling this I get an error when returning Borrower
: 'cannot infer an appropriate lifetime for lifetime parameter 'b
due to conflicting requirements'.编译时,返回Borrower
时出现错误:“由于需求冲突,无法推断生命周期参数'b
的适当生命周期”。 How can I resolve this issue?我该如何解决这个问题? What lifetime parameters can I enter?我可以输入哪些生命周期参数? I feel like both 'a
and 'b
are not the right lifetimes.我觉得'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();
}
}
The issue is specifically in this method:问题特别在于这种方法:
impl<'a, 'b> C<'a, 'b> {
fn get_borrower(&mut self) -> Borrower {
Borrower { ref3: self.ref2 }
}
}
We need to help the compiler understand which lifetime parameters are expected in the returned Borrower
, because the inferred lifetimes here will be incorrect: The lifetime elision Borrower
can be expanded to Borrower<'_, '_>
where the anonymous lifetimes are both the lifetime of &mut self
;我们需要帮助编译器理解在返回的Borrower
需要哪些生命周期参数,因为这里推断的生命周期是不正确的:生命周期省略Borrower
可以扩展为Borrower<'_, '_>
其中匿名生命周期都是生命周期&mut self
; If we call it 's
, the equivalent signature would be:如果我们把它's
,等效签名是:
fn get_borrower<'s>(&'s mut self) -> Borrower<'s, 's> {
This is clearly not right, because we know that the second lifetime is expected to be 'b
, as directly described by field ref2
of type B<'b>
.这显然是不对的,因为我们知道第二个生命周期应该是'b
,正如B<'b>
类型的字段ref2
直接描述的那样。 With the following signature (and after fixing unrelated errors), the code compiles successfully :使用以下签名(并在修复不相关的错误后), 代码编译成功:
fn get_borrower(&mut self) -> Borrower<'_, 'b> {
The fun part is in the first parameter.有趣的部分在第一个参数中。 One could be inclined to assume that we want it to be 'a
instead of 's
, but that would still lead to conflicting lifetimes:人们可能倾向于假设我们希望它是'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<'_, '_>`
This is because we are retrieving ref2
behind a mutable reference to self, and that one has its own lifetime.这是因为我们在对 self 的可变引用后面检索ref2
,并且该引用有自己的生命周期。 We cannot just move it out of self
by force to fulfill the lifetime 'a
, nor can we pass a &'s mut &'a mut B<'b>
instead.我们不能仅仅通过强制将它移出self
来实现生命周期'a
,也不能传递 a &'s mut &'a mut B<'b>
。 Therefore, returning a Borrower<'s, 'b>
is the right thing to do: as it is implicit that 'a: 's
( 'a
outlives 's
), the covariance in this lifetime will enable this method to narrow the mutable reference &'a mut B<'b>
into its subtype &'s mut B<'b>
.因此,返回一个Borrower<'s, 'b>
是正确的做法:因为它隐含着'a: 's
( 'a
outlives 's
),此生命周期中的协方差将使此方法能够缩小可变范围将&'a mut B<'b>
引用到它的子类型&'s mut B<'b>
。
----------
| 'a |
| ------ |
|| 's | ---> Borrower<'s, 'b>
|| | |
| ------ |
----------
See also:也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.