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
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
unwrapit, 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 thenunwrap()if it’s true. That’s not going to crash, but it can get pretty cumbersome. - You can
matchagainst it:match my_option { None => ..., Some(x) => ... }. That’s better, but in this case you’d wind up with amatchinside amatch—which is just confusing to the reader. - There’s a bunch of
.unwrap_or,mapand 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 Bookshelf topics
Other popular topics
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /ruby
- /wasm
- /erlang
- /phoenix
- /keyboards
- /python
- /rails
- /js
- /security
- /go
- /swift
- /vim
- /clojure
- /haskell
- /emacs
- /java
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /flutter
- /elm
- /vscode
- /ash
- /html
- /opensuse
- /centos
- /php
- /zig
- /deepseek
- /scala
- /textmate
- /lisp
- /sublime-text
- /react-native
- /nixos
- /debian
- /agda
- /kubuntu
- /arch-linux
- /django
- /revery
- /deno
- /ubuntu
- /spring
- /nodejs
- /manjaro
- /diversity
- /lua
- /julia
- /slackware
- /c






