问题
struct RefWrap<'a> {
wrap: &'a mut Option<String>,
}
impl<'a> RefWrap<'a> {
fn unwrap(&mut self) -> &'a mut String {
match *self.wrap {
Some(ref mut s) => s,
None => panic!(),
}
}
}
(Playground)
As far as I understand, this code is correct (the returned reference really has the lifetime 'a
. But Rust produces the following error:
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
--> <anon>:8:18
|
8 | Some(ref mut s) => s,
| ^^^^^^^^^
Using immutable references, it works without an error.
There has been one similar question, but I'm pretty sure it's not helpful in this case.
回答1:
It looks like the conflict is that the return value:
- Must be valid for at least the lifetime
'a
- Must not outlive
&mut self
, which is only the lifetime of the function call.
If this were allowed, it would let you call it twice and get two &'a mut
references to the same String
contents:
let mut w = RefWrap { wrap: &mut s };
let ref1 = w.unwrap();
let ref2 = w.unwrap(); // two mutable references!
The reason is that the way Rust reasons about whether something is borrowed is by tying lifetimes together - but here you are explicitly saying that the return value's lifetime is unrelated to &mut self
, which means it doesn't extend the borrow - and then you can borrow again with another call.
The solution here, to get the original reference lifetime out without risking a second &mut
reference overlapping it, is to take self
by value (move) so that it can't be used again. The compiler is happy with this:
impl<'a> RefWrap<'a> {
fn unwrap(self) -> &'a mut String {
match *self.wrap {
Some(ref mut s) => s,
None => panic!(),
}
}
}
(Playground)
来源:https://stackoverflow.com/questions/42397056/cannot-infer-an-appropriate-lifetime-for-pattern-due-to-conflicting-requirement