Lesson 3.2 · 9 min
Choosing with match
An if picks between two roads. Chatterbox needs more: /help should show help, /quit should say goodbye, and everything else should be echoed. For many roads Rust gives you match.
Adds to ChatterboxCommands: /help, /quit.
Arms
A match takes one value and lays out a list of arms. Each arm is a pattern, an arrow =>, and what to do. Rust tries the arms from the top and runs the first one that fits.
$ cargo run
commands: /help, /quitThe first two arms are exact pieces of text. The last arm is just a name, other. A bare name matches anything, and gives that name to the value so you can use it. That is what makes it the "everything else" arm. Try "hello" as the message.
Why the last arm is not optional
Rust makes you cover every possible value. Text can be anything, so with only two arms, what should happen for "hello"? The compiler will not let you leave that undecided:
error[E0004]: non-exhaustive patterns: `&_` not covered --> src/main.rs:3:11 | 3 | match message { | ^^^^^^^ pattern `&_` not covered | = note: the matched value is of type `&str` = note: `&str` cannot be matched exhaustively, so a wildcard `_` is necessary help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | 5 ~ "/quit" => println!("bye!"), 6 ~ &_ => todo!(), |
"non-exhaustive patterns" is the compiler saying: there are values you did not handle. It even suggests a catch-all arm (it prints &_ here, because the value is a &str; _ or a name like other do the same job). The underscore is a catch-all without a name, for when you do not need the value.
This is a gift, not a nuisance. In a chat program that grows a new command next month, the compiler will point at every match that forgot it.
What does this print?
helpecho /Helpquit
Reveal the answer
The program prints: echo /Help Text patterns match exactly, capital letters included. "/Help" is not "/help", so the first two arms are skipped and the catch-all takes it.
Chatterbox v0.3, commands
The empty-message check from last lesson becomes one more arm, "", which is neater than an if next to a match. Commands do not count as messages, so only the catch-all arm touches message_count. Notice an arm can be a block in braces when it needs more than one line.
$ cargo run
Chatterbox v0.3
Hi Sam! I'm Chatterbox.
commands: /help, /quit
messages so far: 0Finish handle: /help gives commands: /help, /quit, /quit gives bye!, an empty message gives (nothing to say), and anything else gives you: plus the text.
Finish handle: /help gives commands: /help, /quit, /quit gives bye!, an empty message gives (nothing to say), and anything else gives you: plus the text.
Hidden tests (4): empty_is_ignored help_lists_commands other_text_is_echoed quit_says_bye
This exercise runs real Rust in your browser through the official Rust Playground, so it needs JavaScript.
Say it out loud, then reveal
What does a bare name like other do as a match arm?Reveal
What does "non-exhaustive patterns" (E0004) mean?Reveal
Does "/Help" match the arm "/help"?Reveal
That is lesson 3.2. Tick it off so the course remembers where you are.