DraganS
DraganS

Reputation: 2699

Difference between if let Some and match

Trying to understand what is wrong in

fn set_inpt_port_values1(&mut self, input_port_values: HashMap<u8, u8>) {
    if let Some(mut io_handler) = self.io_handler {
       io_handler.set_input_ports_values(input_port_values);
    }
}

Getting

cannot move out of `self.io_handler.0` which is behind a mutable referencerustcE0507
i808x.rs(2333, 21): data moved here
i808x.rs(2333, 21): move occurs because `io_handler` has type `Box<dyn IoHandler>`, which does not implement the `Copy` trait
i808x.rs(2333, 39): consider borrowing here

On the other side, the similar function

fn set_inpt_port_values(&mut self, input_port_values: HashMap<u8, u8>) {
    match &mut self.io_handler {
        Some(io_handler) => {
            io_handler.set_input_ports_values(input_port_values);
        }
        _ => (),
    }
}

works/compiles fine (likely set_inpt_port_values doesn't need to be mutable).

The field io_handler is Option<Box<dyn IoHandler>>

pub trait IoHandler {
    fn in_op(&mut self, port: u8) -> u8;
    fn out_op(&mut self, port: u8, byte: u8);
    fn set_input_ports_values(&mut self, input_port_values: HashMap<u8, u8>);
}

Upvotes: 0

Views: 204

Answers (1)

isaactfa
isaactfa

Reputation: 6651

Well, in this statement

if let Some(mut io_handler) = self.io_handler {

you're trying to move self.io_handler into a mutable variable called io_handler. This isn't allowed because that would leave self.io_handler uninitialized.

On the other hand, this match

match &mut self.io_handler {
        Some(io_handler) => {

matches on a &mut Option<Box<dyn IoHandler>> and moves a mutable reference to self.io_handler into an immutable variable called io_handler.

You can achieve the same thing with an if let, by using the ref keyword:

if let Some(ref mut io_handler) = self.io_handler {

This will now try to borrow a mutable reference to whatever is inside that box.

Upvotes: 7

Related Questions