Pattern match and type cast of a mut reference


#1

I want to update the x and y of the struct but I got that movex is of type Move and that it doesn’t have the fields x and y

enum Move {
    Move2 { x: i32, y: i32 },
    Move3 { x: i32, y: i32, z: i32 },
}

fn do_move(move_origin: &mut Move, movement: &Move) {
    match (move_origin, movement) {
        (movex @ &mut Move::Move2 { .. }, &Move::Move2 { x, y }) => {
            movex.x += x;
            movex.y += y
        }
        _ => println!("Moving in 3"),
    };
}

#2

I just past the code since I’m to tiered and don’t find the words to explain it

fn do_move(move_origin: &mut Move, movement: &Move) {
    match (move_origin, movement) {
        (
            &mut Move::Move2 {x: ref mut orig_x, y: ref mut orig_y},
            &Move::Move2 { x, y },
        ) => {
            *orig_x += x;
            *orig_y += y
        }
        
        _ => println!("Moving in 3"),
    };
}

edit: ok i was sleeping a bit

the reason your version isn’t working is that the ‘@’ binding neither destructs nor cast the enum there is no way i know of to access field in a enum over the ‘.field’ syntax you have to destruct the enum.
The destruction is possible in a bunch of different ways

fn main() {
    let mut opt: Option<u32> = Some(42);

    println!("by value");
    // this will move the val out of the enum copying if necessary and posible
    match opt {
        Some(val) => println!("val: {}", val), // here val is of type 'u32'
        None => panic!(),
    }
    println!("opt: {:?}\n", opt);

    println!("by mut value");
    // the same but val is mutable keep in mind that you work on a copy of the value
    // and changes to it will not be visible on the original enum
    match opt {
        Some(mut val) => {
            // here val is of type 'mut u32'
            val += 1;
            println!("val: {}", val)
        }
        None => panic!(),
    }
    println!("opt: {:?}\n", opt);

    println!("by ref");
    // this will give you a reference to the value inside the enum
    match opt {
        Some(ref val) => println!("val: {}", val), // here val is of type '&u32'
        None => panic!(),
    }
    println!("opt: {:?}\n", opt);

    println!("by ref mut");
    // and this will give you a mutable reference to the value inside the enum
    // here you can chnge the value and it will be visible later o the oriinal enum
    match opt {
        Some(ref mut val) => {
            *val += 1; // here val is of type '&mut u32'
            println!("val: {}", val)
        }
        None => panic!(),
    }
    println!("opt: {:?}\n", opt);
}

#3

Thanks, btw I’m learning Rust, I was trying to do it how I will in Elixir