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

jamis
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
lirux
Hi Jamis, I think there’s an issue with a test on chapter 6. I own the ebook, version P1.0 Feb. 2019. This test doesn’t pass for me: ...
New
mikecargal
Title: Hands-on Rust: question about get_component (page 295) (feel free to respond. “You dug you’re own hole… good luck”) I have somet...
New
raul
Hi Travis! Thank you for the cool book! :slight_smile: I made a list of issues and thought I could post them chapter by chapter. I’m rev...
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
gilesdotcodes
In case this helps anyone, I’ve had issues setting up the rails source code. Here were the solutions: In Gemfile, change gem 'rails' t...
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
jskubick
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint. As entered, the SwitchCompat changes color to hol...
New
jgchristopher
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ” Excerpt From: Br...
New
dsmith42
Hey there, I’m enjoying this book and have learned a few things alredayd. However, in Chapter 4 I believe we are meant to see the “&gt;...
New

Other popular topics Top

AstonJ
What chair do you have while working… and why? Is there a ‘best’ type of chair or working position for developers?
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
dasdom
No chair. I have a standing desk. This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
AstonJ
Biggest jackpot ever apparently! :upside_down_face: I don’t (usually) gamble/play the lottery, but working on a program to predict the...
New
PragmaticBookshelf
Author Spotlight Mike Riley @mriley This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
PragmaticBookshelf
Author Spotlight: VM Brasseur @vmbrasseur We have a treat for you today! We turn the spotlight onto Open Source as we sit down with V...
New
PragmaticBookshelf
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New
hilfordjames
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New

Sub Categories: