Lesson 5.4 · 9 min
Maybe nothing: Option
What is the argument of "/help"? There is not one. Many languages answer with null and let you find out later. Rust makes "maybe nothing" a type, so you must decide up front.
Adds to Chatterboxfind_command_arg() returns an Option; the bot replies with a Message.
A value that may not be there
A chat command can have an argument: the hello in /say hello. But /help has none. A function that looks for the argument will sometimes come back with nothing.
Rust has no null. Instead, a value that might be missing has its own type, Option<T>, which is just an enum (lesson 5.3) with two variants: Some(value) and None.
$ cargo run
Some("hello")
Noneline.find(' ') is itself an Option ({:?} in println! prints a value in debug form, which is how Some("hello") shows; later, matches!(x, Pat) is a yes/no match): the position of the first space, or nothing. if let Some(i) = ... reads "if this is a Some, call what is inside i and run the block; otherwise run the else". It is a match with just the one arm you care about.
The return type Option<&str> is a borrowed slice (lesson 4.5) that may be absent. It points into line, so nothing is copied.
You cannot use it as if it were there
error[E0308]: mismatched types --> src/main.rs:10:21 | 10 | let arg: &str = find_command_arg("/help"); | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `Option<&str>` | | | expected due to this | = note: expected reference `&str` found enum `Option<&str>` help: consider using `Option::expect` to unwrap the `Option<&str>` value, panicking if the value is an `Option::None` | 10 | let arg: &str = find_command_arg("/help").expect("REASON"); | +++++++++++++++++
E0308: "mismatched types: expected &str, found Option<&str>". The compiler is saying: this might be nothing, so you cannot treat it as text yet. That is the whole trick. In a language with null, this compiles and crashes when the line was /help. Here the crash is not expressible.
The simplest way out is unwrap_or: "give me the value, or this fallback if there is none".
What does this print?
hi | nonehi |it panics
Reveal the answer
The program prints: hi | none a is Some("hi"), so unwrap_or returns hi. b is None, so it returns the fallback. The fallback is decided by you, in the code, and never skipped.
Chatterbox v0.5: parse, handle, a Message out
Chapter 5 comes together. A typed line becomes a Command in parse; find_command_arg pulls out the argument (a bare /say is handled explicitly, and /say with the space is what an argument needs, as in 5.3), and unwrap_or("") says what a bare /say means. handle turns the command into a reply Message. The help text now lists /say, and a reply is a Message from bot instead of an echo: string. matches!(cmd, Command::Quit) in main is a yes/no match.
$ cargo run
bot: commands: /help /quit /say <text>
bot: hello
bot:
bot: unknown: /dance
bot: byeRun it and watch the last line: after /quit the loop breaks, so /say never is never handled. The program now parses text into a typed value, handles every case the compiler can see, and has no null anywhere. Chapter 6 gives it a memory: the whole conversation in a list.
Write shout_arg. If the line has an argument, return it in UPPERCASE. If it has none, return NOTHING TO SHOUT. find_command_arg is given.
Write shout_arg. If the line has an argument, return it in UPPERCASE. If it has none, return NOTHING TO SHOUT. find_command_arg is given.
Hidden tests (3): keeps_the_whole_argument nothing_to_shout shouts_the_argument
This exercise runs real Rust in your browser through the official Rust Playground, so it needs JavaScript.
Say it out loud, then reveal
What are the two variants of <code>Option<T></code>?Reveal
Some(value) when there is a value and None when there is not.Why does Rust refuse to use an <code>Option<&str></code> where a <code>&str</code> is expected?Reveal
None first, with match, if let or unwrap_or, so a missing value can never crash the program by surprise.What does <code>unwrap_or("none")</code> do?Reveal
Some, or the fallback you gave if it is None.That is lesson 5.4. Tick it off so the course remembers where you are.