use std::ops::Add;
#[derive(Debug)]
struct Sample {
pub value: usize,
}
impl std::ops::Add<&Sample> for &Sample {
type Output = Sample;
fn add(self, other: &Sample) -> Sample {
Sample {
value: self.value + other.value,
}
}
}
fn main() {
let mut a = Sample { value: 0 };
let b = Sample { value: 1 };
let mut_a = &mut a;
let immut_b = &b;
println!("Works: {:?}", mut_a.add(immut_b));
println!("And this works: {:?}", immut_b.add(mut_a));
println!("Also works:: {:?}", immut_b + mut_a);
println!("Still works:: {:?}", &*mut_a + immut_b);
println!("Fails: {:?}", mut_a + immut_b);
}
In this codeadd
takes two &Sample
s. In the main method, I create two references to two different Sample
s, one mutable and one immutable. I can call explicitly call add
on them in either order, but if I use the +
operator, it complains if the mutable reference comes first. (Re-borrowing it as immutable also makes it work.) I would expect a mutable reference to be valid anywhere an immutable one is. What gives?
Deepening the mystery, I tried to do the same with basic i32
s -
let mut x: i32 = 0;
let y: i32 = 1;
let mut_x = &mut x;
let immut_y = &y;
println!("But this doesn't work? {:?}", immut_y + mut_x);
println!("Or this? {:?}", mut_x + immut_y);
println!("And this does? {:?}", mut_x.add(immut_y));
println!("But not this? {:?}", immut_y.add(mut_x));S
And got a completely different unexpected behavior - now I can't add them in either order with the +
operator, and the explicit call only works if the function is called on the mutable.