Hi all, I've been learning Rust by starting with a basic Piston set up and iterating on a simple game. I ran into a situation with using match, and while I ended up with a solution that works for me, I don't quite understand the reason I had to do what I did. I'm hoping someone can explain what I'm missing.
So, I'm writing code to detect keyboard key press releases. I started out with this:
fn release(&mut self, args: &Button) {
if let Keyboard(button) = *args {
match button {
Key::A => println!("Released A"),
Key::S => println!("Released S"),
Key::D => println!("Released D"),
Key::W => println!("Released W"),
_ => (),
}
}
}
Okay, that worked great!
Next, I add a key_state
field to self
, choosing a key_state: HashSet<Key>
type, which seemed good to me. In doing that, I'm going to add and remove keys to the key_state
as they're pressed and released, respectively, so that I can track the set of keys currently depressed. I want to do that to allow for diagonal movement and to bypass debouncing issues I'd been seeing.
My next iteration on the function is (focusing just on the match, that's the only part changing):
match button {
Key::A => self.key_state.remove(&button),
Key::S => self.key_state.remove(&button),
Key::D => self.key_state.remove(&button),
Key::W => self.key_state.remove(&button),
_ => (),
}
Building that, I get this error:
error[E0308]: match arms have incompatible types
--> src/lib.rs:70:13
|
70 | / match button {
71 | | Key::A => self.key_state.remove(&button),
72 | | Key::S => self.key_state.remove(&button),
73 | | Key::D => self.key_state.remove(&button),
74 | | Key::W => self.key_state.remove(&button),
75 | | _ => (),
76 | | }
| |_____________^ expected bool, found ()
|
= note: expected type `bool`
found type `()`
note: match arm with an incompatible type
--> src/lib.rs:75:22
|
75 | _ => (),
|
Ah, of course, remove
returns a bool
, simple mistake. So, I change:
_ => (),
to:
_ => false,
Because I don't really care about the returned value, I just want to avoid a long winded chain of if let
statements. But, to my surprise, the compiler tells me:
error[E0308]: mismatched types
--> src/lib.rs:70:13
|
70 | / match button {
71 | | Key::A => self.key_state.remove(&button),
72 | | Key::S => self.key_state.remove(&button),
73 | | Key::D => self.key_state.remove(&button),
74 | | Key::W => self.key_state.remove(&button),
75 | | _ => false,
76 | | }
| |_____________^ expected (), found bool
|
= note: expected type `()`
found type `bool`
Wut? I went back and forth changing _ =>
's result between ()
and false
, and it just kept oscillating errors on me. Eventually, I arrived at:
fn release(&mut self, args: &Button) {
if let Keyboard(button) = *args {
use Key::*;
match button {
A | S | D | W => { self.key_state.remove(&button); },
_ => (),
}
}
}
Which works great. Now, I understand that { self.key_state.remove(&button); }
returns ()
, so that's why it's fine, but I don't understand why my change to:
_ => false,
Didn't work. I'm pretty sure I'm just missing something subtle with the way the code's evaluated, but I just can't see it. Any help?