2

The Rust book calls the ref keyword "legacy". As I want to follow the implicit advice to avoid ref, how can I do it in the following toy example? You can find the code also on the playground.

struct OwnBox(i32);

impl OwnBox {
    fn ref_mut(&mut self) -> &mut i32 {
        match *self {
            OwnBox(ref mut i) => i,
        }

        // This doesn't work. -- Even not, if the signature of the signature of the function is
        // adapted to take an explcit lifetime 'a and use it here like `&'a mut i`.
        // match *self {
        //     OwnBox(mut i) => &mut i,
        // }

        // This doesn't work
        // match self {
        //     &mut OwnBox(mut i) => &mut i,
        // }
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
user2292040
  • 305
  • 1
  • 7
  • 1
    I think the book is wrong to call these "legacy"; as it points out, you still need them in some situations, and sometimes it can be clearer to use `ref`. So, definitely be aware of "pattern ergonomics" and how it works, but also I don't think you should go out of your way to avoid `ref` and `ref mut`. – trent Mar 12 '19 at 21:49

1 Answers1

6

Since self is of type &mut Self, it is enough to match against itself, while omitting ref entirely. Either dereferencing it with *self or adding & to the match arm would cause an unwanted move.

fn ref_mut(&mut self) -> &mut i32 {
    match self {
        OwnBox(i) => i,
    }
}

For newtypes such as this one however, &mut self.0 would have been enough.

This is thanks to RFC 2005 — Match Ergonomics.

wigy
  • 2,174
  • 19
  • 32
E_net4
  • 27,810
  • 13
  • 101
  • 139