Option struct

The Problem

Consider that you want to implement a function that returns a username, given the corresponding user identifier. The signature of the function could be as follows:

fn get_username_by_id(id: u32) -> String {
    // function body
}

In a success case, you pass the user identifier as a parameter and the function returns the corresponding username. However, what happens if the function does not have a username for the given identifier? A possible solution is to return an empty string:

  • If the function is able to retrieve the data, then the string returned is the username.

  • If the function is NOT able to retrieve the data, then the string returned is the empty string ('').

Although this is a valid approach, it creates hidden logic that is not visible unless you deep dive into the function code.

The Solution

Rust provides a better way of dealing with these situations by using the Option<T> enum. This enum has two possible values: Some(T) (used when the returned value is present) and None (used when the returned value is not present). Therefore, the previous function can be refactored to:

fn get_username_by_id(id: u32) -> Option<String> {
    // function body
}

Now, the function works as follows:

  • If the function is able to retrieve the data, then a Some value containing the string is returned.

  • If the function is NOT able to retrieve the data, then a None value is returned.

Let's complete the body of the function:

  1. Given a user identifier, return the corresponding username if it exists.

  2. If id == 1, then a Some struct containing the string is returned.

  3. If id == 2, then a Some struct containing the string is returned.

  4. If id does not match with any of the provided identifiers, then a None struct is returned.

Using Options

The Option<T> struct contains two helper methods to check if the returned type is Some or None: the .is_some() and .is_none() methods. Let's see how to use these methods:

  1. Get the user with id == 1.

  2. Get the user with id == 10.

  3. If the function returned a name for id == 1, then user1.is_some() returns true.

  4. If the function did NOT return a name for id == 10, then user1.is_none() returns true.

You can also use pattern matching instead of the helper methods:

Last updated

Was this helpful?