Chocrates

Chocrates

Hands-on Rust: Why Some(key) in Chapter 3

I don’t know the exact page unfortunately since I am reading it in an epub.

I am having trouble understanding what this code does and why it is needed:

​ 	​fn​ ​dead​(&​mut​ ​self​, ctx: &​mut​ BTerm) {
​ 	    ...
​ 	    ​if​ ​let​ ​Some​(key) = ctx.key {
​ 	        ​match​ key {
​ 	            ​VirtualKeyCode​::P ​=>​ ​self​​.restart​(),
​ 	            ​VirtualKeyCode​::Q ​=>​ ctx.quitting = ​true​,
​ 	            _ ​=>​ {}
​ 	        }
​ 	    }
​ 	}

What exactly does the Some(key) bit do? Is it destructuring the Option<bracket_lib::prelude::VirtualKeyCode> object?
Just switching on ctx.key obviously doesn’t work, but I don’t quite get why.

First Post!

herbert

herbert

Author of Hands-on Rust

Hi!

ctx.key is an Option type - it has two possible values: None (there is no data), or Some(x). In other languages, it’s often referred to as a Maybe.

In this case, if no key is pressed then ctx.key will equal None. If a key is pressed, then it will equal Some(VirtualKeyCode::key).

There’s a few ways to get the contents of an Option:

  • You can unwrap it, which gives you the inner value - and crashes the program if there isn’t one. That’s probably not a good choice for reading keyboard input!
  • You can query my_option.is_some() and then unwrap() if it’s true. That’s not going to crash, but it can get pretty cumbersome.
  • You can match against it: match my_option { None => ..., Some(x) => ... }. That’s better, but in this case you’d wind up with a match inside a match—which is just confusing to the reader.
  • There’s a bunch of .unwrap_or, map and similar functionality that I didn’t want to touch so early in the book.

So Rust introduced if let. It’s a hybrid of if and match. It can be broken into: if (pattern) matches (variable/expression). If the pattern matches, it runs the enclosed code. If it doesn’t match, it doesn’t (but like if, you can use an else if you wish). On top of that, it does match style destructuring of the specified pattern. It’s invaluable, but a little tricky to get your head around.

So: if let Some(key) = ctx.key takes the contents of ctx.key, which is an Option. If that matches Some(key) then it destructures key to be the contents of the Option. Inside the if let scope block you can then use key like any other variable.

In other words, it’s the same as:

match ctx.key {
    Some(key) => {
        match key {
            VirtualKeyCode::P => self.restart(),
            //(etc)
        }
    }
    None => {} // Do nothing
}

You’ll find if let used a lot in Rust. It works with any pattern matchable expression. You could use if let VirtualKeyCode::P == key to match on a single enum entry. if let Ok(result) = my_dangerous_function_that_returns_a_result() is a common way to extract the “it worked” path from functions that return errors - and so on.

Hope that helps!

Where Next?

Popular Pragmatic Bookshelf topics Top

jesse050717
Title: Web Development with Clojure, Third Edition, pg 116 Hi - I just started chapter 5 and I am stuck on page 116 while trying to star...
New
sdmoralesma
Title: Web Development with Clojure, Third Edition - migrations/create not working: p159 When I execute the command: user=&gt; (create-...
New
leonW
I ran this command after installing the sample application: $ cards add do something --owner Brian And got a file not found error: Fil...
New
patoncrispy
I’m new to Rust and am using this book to learn more as well as to feed my interest in game dev. I’ve just finished the flappy dragon exa...
New
digitalbias
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64) If you follow the defau...
New
oaklandgit
Hi, I completed chapter 6 but am getting the following error when running: thread 'main' panicked at 'Failed to load texture: IoError(O...
New
ggerico
I got this error when executing the plot files on macOS Ventura 13.0.1 with Python 3.10.8 and matplotlib 3.6.1: programming_ML/code/03_...
New
bjnord
Hello @herbert ! Trying to get the very first “Hello, Bracket Terminal!" example to run (p. 53). I develop on an Amazon EC2 instance runn...
New
redconfetti
Docker-Machine became part of the Docker Toolbox, which was deprecated in 2020, long after Docker Desktop supported Docker Engine nativel...
New
SlowburnAZ
Getting an error when installing the dependencies at the start of this chapter: could not compile dependency :exla, "mix compile" failed...
New

Other popular topics Top

ohm
Which, if any, games do you play? On what platform? I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
AstonJ
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
Exadra37
I am asking for any distro that only has the bare-bones to be able to get a shell in the server and then just install the packages as we ...
New
New
AstonJ
Saw this on TikTok of all places! :lol: Anyone heard of them before? Lite:
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
PragmaticBookshelf
Author Spotlight: Peter Ullrich @PJUllrich Data is at the core of every business, but it is useless if nobody can access and analyze ...
New
Fl4m3Ph03n1x
Background Lately I am in a quest to find a good quality TTS ai generation tool to run locally in order to create audio for some videos I...
New
mindriot
Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
New

Sub Categories: