
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
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 thenunwrap()
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 amatch
inside amatch
—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










Other popular topics










Latest in PragProg
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /ash
- /centos
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /react-native
- /textmate
- /sublime-text
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /manjaro
- /spring
- /django
- /diversity
- /nodejs
- /lua
- /slackware
- /julia
- /c
- /neovim