Implementing Trait AddAssign with struct generic


#1

Hi i’m tryng to undestand the trait implementation with “Mastering Rust” of Vesa Kaihlavirta
In the chapter 4 a task is to implement Add,Sub,AddAssign trait.
The task work fine with a struct not generic, when i try to implement the trait AddAssign in a generic struct i have an error.

                     saldo:self.saldo+rhs.saldo,**
                               ^^^^ cannot move out of borrowed content**
                     valuta:self.valuta**
                                ^^^^ cannot move out of borrowed content**                         

#[derive(Debug)]
struct MyMoney {
saldo:T,
valuta:String
}

impl<T: Add<T,Output=T>> Add for MyMoney {
type Output=MyMoney;
fn add(self,rhs:MyMoney) -> Self::Output {
assert!(self.valuta==rhs.valuta);
MyMoney{valuta:self.valuta,saldo:self.saldo+rhs.saldo}

}

}

impl<T: Sub<T,Output=T>> Sub for MyMoney {
type Output=MyMoney;
fn sub(self,rhs:MyMoney) -> Self::Output {
assert!(self.valuta==rhs.valuta);
MyMoney{valuta:self.valuta,saldo:self.saldo-rhs.saldo}

}

}

impl<T: Add<Output=T>> AddAssign for MyMoney {
fn add_assign(&mut self,rhs:MyMoney) {
*self= MyMoney{
saldo:self.saldo+rhs.saldo,
valuta:self.valuta
};
}
}

fn main() {
{
let a_0:MyMoney=MyMoney{saldo:100000,valuta:“YEN”.to_string()};
let a_1:MyMoney=MyMoney{saldo:1000000,valuta:“YEN”.to_string()};
let a_2=a_0+a_1;
println!(“a_2 {:#?}”,a_2);
}

{
    let a_0:MyMoney<isize>=MyMoney{saldo:100000,valuta:"YEN".to_string()};
    let a_1:MyMoney<isize>=MyMoney{saldo:1000000,valuta:"YEN".to_string()};
    let a_2=a_0-a_1;
    println!("a_2 sub {:#?}",a_2);
}


    let mut a_3:MyMoney<i32>=MyMoney{saldo:1000,valuta:"YEN".to_string()};
    a_3+=MyMoney{saldo:1000_i32,valuta:"----".to_string()};
println!("a_3 sub {:#?}",a_3);

}

thanks Alex


#2

AddAssign should look like this:

impl<T: AddAssign> AddAssign for MyMoney<T> {
    fn add_assign(&mut self, rhs: Self) {
        self.saldo += rhs.saldo;
    }
}

There’s no need to try and replace self.

Here’s a full working playground with your code (fixed up).


#3

Put another way, assign operators are statement level and thus must return a (), but your original signature Output=T had AddAssign returning an expression.