Search code examples
enumsrustself

Mutating self in enum method


This is cobbled together to illustrate the problem that I have with the switch function. I do not have problem printing "Left" "Right" endlessly.

The point of switch is to swap the value of enum to another. This solution doesn't work because presumably the switch moves t into itself so it's no longer usable. Use of mutable references causes a whole host of other problems, like with lifetime and mismatched types. The documentation had instructions how to do this with structs, but not enums. The compiler suggested implementing Copy and Clone to the enum, but that did nothing useful.

How is this type of method supposed to be made in Rust?

fn main() {
    let mut t = Dir::Left;

    loop {
        match &t {
            &Dir::Left => println!("Left"),
            &Dir::Right => println!("Right"),
        }

        t.switch();
    }
}

enum Dir {
    Left,
    Right,
}

impl Dir {
    //this function is the problem here
    fn switch(mut self) {
        match self {
            Dir::Left => self = Dir::Right,
            Dir::Right => self = Dir::Left,
        };
    }
}

Of course I could just make it so

t = t.switch();

and

fn switch(mut self) -> Self {
    match self {
        Dir::Left  => return Dir::Right,
        Dir::Right => return Dir::Left,
    };
}

But I feel that would be comparatively clumsy solution, and I would like to avoid it if at all possible.


Solution

  • Your method consumes your data instead of borrowing it. If you borrow it, it works fine:

    impl Dir {
        fn switch(&mut self) {
            *self = match *self {
                Dir::Left => Dir::Right,
                Dir::Right => Dir::Left,
            };
        }
    }