Hello,
I do not understand why Ref::f
compiles but RefMut::f
does not:
struct Ref<'a>{
val: &'a f64
}
impl<'a> Ref<'a> {
fn f(&self) -> &'a f64 {
self.val
}
}
struct RefMut<'a>{
val: &'a mut f64
}
impl<'a> RefMut<'a> {
fn f(&self) -> &'a f64 {
self.val //COMPILER ERROR: lifetime may not live long enough
}
}
Some one could explain me please?
For Ref
, &
references implement Copy
, so the function is able to just return a copy of the reference stored in the struct. For RefMut
, &mut
references can't implement Copy
, since they need to be unique. That means the only way the &mut
reference can be returned is either by moving it out (which requires that you either replace it with another reference or that you have ownership of the struct and destroy it, neither of which work well here) or reborrowing through the self
reference (which has the lifetime parameter of that reference rather than 'a
, yielding the error you get since the lifetimes don't match).
8 Likes
And to explain why the compiler error is correct: if your code could compile, you could call f
and get a &'a f64
that remains valid after the &self
reference expired and made the val: &'a mut f64
usable/"active" again. That is, you have an active &'a mut _
and &'a _
which alias each other, which is undefined behavior.
Example.
3 Likes
I understand better the borrow rules thanks to you, tx.
struct RefMut<'a> {
val: &'a mut f64,
}
impl<'a> RefMut<'a> {
fn f<'s: 'a>(&'s self) -> &'a f64 {
self.val //COMPILES
}
}
1 Like