Search code examples
pointersrustdereference

"*value += how_much" vs "*value += *how_much" in rust?


In the following rust code, why do both of the functions mutate_value() work with and without dereferencing the how_much param? Shouldn't this not work since I am adding a reference to the value?

fn mutate_value(value: &mut i32, how_much: &i32) {
    *value += how_much
}

// fn mutate_value(value: &mut i32, how_much: &i32) {
//    *value += *how_much
// }


fn main() {
    let mut value = 5;
    let how_much = 10;
    mutate_value(&mut value, &how_much);
    println!("value: {}", value);
}

Solution

  • i32, as well as the other number primitives, implements AddAssign for two different right-hand-side types.

    Your two functions use each of these respectively. You can see it clearly when the AddAssign impls aren't the same. (playground)

    #[derive(Debug, Clone, Copy)]
    struct A(i32);
    
    impl AddAssign for A {
        fn add_assign(&mut self, other: A) {
            println!("By value");
            self.0 += other.0;
        }
    }
    
    impl AddAssign<&A> for A {
        fn add_assign(&mut self, other: &A) {
            println!("By reference");
            // The . operator dereferences
            self.0 += other.0;
        }
    }
    
    fn main() {
        let mut a = A(4);
        let b = A(6);
        // By value
        a += b;
        let c = &b;
        // By reference
        a += c;
        dbg!(a);
    }