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!

Popular Pragmatic topics Top

kuroneko
Whilst the author has been careful to provide exact results for the tests elsewhere in the book (such as surds with the transformation te...
New
iPaul
page 37 ANTLRInputStream input = new ANTLRInputStream(is); as of ANTLR 4 .8 should be: CharStream stream = CharStreams.fromStream(i...
New
belgoros
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84: bundle exec sequel...
New
johnp
Hi Brian, Looks like the api for tinydb has changed a little. Noticed while working on chapter 7 that the .purge() call to the db throws...
New
yulkin
your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
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
New
adamwoolhether
When trying to generate the protobuf .go file, I receive this error: Unknown flag: --go_opt libprotoc 3.12.3 MacOS 11.3.1 Googling ...
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
adamwoolhether
I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New

Other popular topics Top

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
We have a thread about the keyboards we have, but what about nice keyboards we come across that we want? If you have seen any that look n...
New
AstonJ
Just done a fresh install of macOS Big Sur and on installing Erlang I am getting: asdf install erlang 23.1.2 Configure failed. checking ...
New
AstonJ
Inspired by this post from @Carter, which languages, frameworks or other tech or tools do you think is killing it right now? :upside_down...
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
PragmaticBookshelf
Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New
PragmaticBookshelf
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
New
PragmaticBookshelf
Author Spotlight: Karl Stolley @karlstolley Logic! Rhetoric! Prag! Wow, what a combination. In this spotlight, we sit down with Karl ...
New
PragmaticBookshelf
Author Spotlight: Tammy Coron @Paradox927 Gaming, and writing games in particular, is about passion, vision, experience, and immersio...
New

Latest in PragProg

View all threads ❯