Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does `ref` causes this example to *dereference* a field?

Tags:

rust

I encountered the following (reduced) example:

enum Thing {
    A { value: f32 },
    B { value: f32 },
}


fn main() {

    let mut thing = Thing::A { value: 0. };
    let thing_mut_ref = &mut thing;


    if let Thing::A {value} = thing_mut_ref {
        *thing_mut_ref = Thing::B { value: value * 2.0};
    }   
    
   
}

The following does not compile because value is captured as a &mut f32, and thus does not support multiplying by 2.0.

What surprised me was that adding ref to the matched pattern suddenly makes it compile, i.e. captures by value (dereferences value):

enum Thing {
    A { value: f32 },
    B { value: f32 },
}


fn main() {

    let mut thing = Thing::A { value: 0. };
    let thing_mut_ref = &mut thing;


    if let Thing::A {ref value} = thing_mut_ref {
        *thing_mut_ref = Thing::B { value: value * 2.0};
    }   
}

I know ref for usually doing the opposite - stating that we do not want to capture by value. How does this explain what is going on here?

like image 353
Alex Hastings Avatar asked Feb 25 '26 15:02

Alex Hastings


1 Answers

It does not in fact dereference but convert the mutable reference into a shared one. And as you can see from the documentation of Mul it is implemented for &f32 and f32 but not for &mut f32

like image 123
cafce25 Avatar answered Feb 28 '26 13:02

cafce25



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!