Rust Fundamentals · 15 XP Pro

Option

Rust has no null. When a value might be missing, the type says so with the standard enum Option<T>:

enum Option<T> {
    Some(T),
    None,
}

A function that may fail to find something returns Option, and the caller must deal with None before touching the value inside.

fn first_char(s: &str) -> Option<char> {
    s.chars().next()
}

match first_char("hi") {
    Some(c) => println!("starts with {c}"),
    None => println!("empty"),
}

Some and None are in scope everywhere, so no Option:: prefix is needed.

Writing a match each time gets long, so Option has helper methods:

  • opt.unwrap_or(default) gives the inner value, or default when it is None.
  • opt.map(|v| ...) applies a closure to the value inside Some and leaves None alone. The result is another Option.
let n: Option<i32> = Some(4);
assert_eq!(n.map(|v| v + 1), Some(5));
assert_eq!(None.unwrap_or(0), 0);

Avoid unwrap(): it panics on None.

Your task

Everything must be pub. Write:

  1. pub fn safe_divide(a: i32, b: i32) -> Option<i32>: None when b is 0, otherwise Some(a / b).
  2. pub fn first_even(nums: &[i32]) -> Option<i32>: the first even number, or None.
  3. pub fn name_or_guest(name: Option<&str>) -> String: the name as a String, or "guest" if there is none. Try unwrap_or.
  4. pub fn double_if_some(x: Option<i32>) -> Option<i32>: doubles the inner value. Try map.

Next lesson →

Sign in to run your code. It's free.