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

brianokken
Many tasks_proj/tests directories exist in chapters 2, 3, 5 that have tests that use the custom markers smoke and get, which are not decl...
New
Mmm
Hi, build fails on: bracket-lib = “~0.8.1” when running on Mac Mini M1 Rust version 1.5.0: Compiling winit v0.22.2 error[E0308]: mi...
New
herminiotorres
Hi! I know not the intentions behind this narrative when called, on page XI: mount() |&gt; handle_event() |&gt; render() but the correc...
New
conradwt
First, the code resources: Page 237: rumbl_umbrella/apps/rumbl/mix.exs Note: That this file is missing. Page 238: rumbl_umbrella/app...
New
jskubick
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
jskubick
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint. As entered, the SwitchCompat changes color to hol...
New
Charles
In general, the book isn’t yet updated for Phoenix version 1.6. On page 18 of the book, the authors indicate that an auto generated of ro...
New
AufHe
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113. Iteration A1 - Seeing the list of prod...
New
jwandekoken
Book: Programming Phoenix LiveView, page 142 (157/378), file lib/pento_web/live/product_live/form_component.ex, in the function below: d...
New
tkhobbes
After some hassle, I was able to finally run bin/setup, now I have started the rails server but I get this error message right when I vis...
New

Other popular topics Top

AstonJ
Thanks to @foxtrottwist’s and @Tomas’s posts in this thread: Poll: Which code editor do you use? I bought Onivim! :nerd_face: https://on...
New
Exadra37
On modern versions of macOS, you simply can’t power on your computer, launch a text editor or eBook reader, and write or read, without a ...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
PragmaticBookshelf
“Finding the Boundaries” Hero’s Journey with Noel Rappin @noelrappin Even when you’re ultimately right about what the future ho...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
PragmaticBookshelf
“A Mystical Experience” Hero’s Journey with Paolo Perrotta @nusco Ever wonder how authoring books compares to writing articles?...
New
AstonJ
Continuing the discussion from Thinking about learning Crystal, let’s discuss - I was wondering which languages don’t GC - maybe we can c...
New
PragmaticBookshelf
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
First poster: bot
The overengineered Solution to my Pigeon Problem. TL;DR: I built a wifi-equipped water gun to shoot the pigeons on my balcony, controlle...
New
DevotionGeo
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New

Sub Categories: