ifletSome和match的区别
试图了解什么是错误的
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);
}
}
得到
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
另一方面,类似的功能
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);
}
_ => (),
}
}
工作/编译正常(可能set_inpt_port_values不需要可变)。
字段 io_handler 是 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>);
}
回答
那么,在这个声明中
if let Some(mut io_handler) = self.io_handler {
您正试图self.io_handler进入一个名为io_handler. 这是不允许的,因为这会导致self.io_handler未初始化。
另一方面,这 match
match &mut self.io_handler {
Some(io_handler) => {
上的匹配&mut Option<Box<dyn IoHandler>>,并移动一个可变引用到self.io_handler成称为一个不可变的变量io_handler。
您可以使用 if let 来实现相同的目的,方法是使用ref关键字:
if let Some(ref mut io_handler) = self.io_handler {
现在,这将尝试借用对该框内任何内容的可变引用。
- 您也可以使用`if let Some(io_handler) = &mut self.io_handler {`(左侧的`ref` 相当于右侧的`&`)实现同样的效果,但我同意`当有许多变量要提取时,ref` 可以实现更多的微妙之处。