Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. Result::unwrap() / expect() / ? Operator

Result::unwrap() / expect() / ? Operator

Since: Rust 1.0(2015)

Methods for extracting values from Result, and the ? operator for automatically propagating errors to the caller. The ? operator in particular can significantly reduce error-handling boilerplate.

Syntax

let value = result.unwrap();

// Panics with the specified message if Err.
let value = result.expect("error message");

let value = result.unwrap_or(default_value);

// Propagates the error to the caller if Err (the ? operator).
// Can only be used inside a function that returns Result.
let value = some_func()?;

Method List

Method / OperatorDescription
unwrap()Returns x if the value is Ok(x), or panics if it is Err. Using this outside of prototypes and test code carries a risk of panic.
expect("msg")Same as unwrap(), but displays the specified message on panic. Makes it easier to identify the cause of the error.
unwrap_or(val)Returns the default value if the result is Err. Use this when you want to ignore the error and continue processing.
unwrap_or_else(fn)Runs a closure that receives the error value when the result is Err(e). You can return a default value based on the error's content.
? operatorReturns x if the value is Ok(x), or immediately returns the error to the caller if it is Err(e). Can only be used in functions that return Result (or Option).
ok() / err()Converts a Result into an Option. ok() converts Ok(x) to Some(x) and Err to None.

Sample Code

sample_result_unwrap_question.rs
use std::num::ParseIntError;

// Propagates errors to the caller using the ? operator.
fn parse_and_double(s: &str) -> Result<i32, ParseIntError> {
    let n = s.parse::<i32>()?; // Returns Err immediately if parsing fails.
    Ok(n * 2)
}

// Example of chaining multiple ? operators.
fn parse_sum(a: &str, b: &str) -> Result<i32, ParseIntError> {
    let x = a.parse::<i32>()?;
    let y = b.parse::<i32>()?;
    Ok(x + y)
}

fn main() {
    // Calling functions that use the ? operator.
    println!("{:?}", parse_and_double("5")); // Ok(10)
    println!("{:?}", parse_and_double("abc")); // Err(...)

    println!("{:?}", parse_sum("3", "4")); // Ok(7)
    println!("{:?}", parse_sum("3", "x")); // Err(...)

    // Using unwrap_or to fall back to a default value on error.
    let n = "abc".parse::<i32>().unwrap_or(0);
    println!("{}", n); // 0

    // Using unwrap_or_else to handle the error value.
    let n = "abc".parse::<i32>().unwrap_or_else(|e| {
        println!("Parse error: {}", e);
        -1
    });
    println!("{}", n); // -1

    // Converting a Result to an Option with ok().
    let opt = "42".parse::<i32>().ok();
    println!("{:?}", opt); // Some(42)
}

Compile with the following command:

rustc result_unwrap_question.rs
./result_unwrap_question
Ok(10)
Err(ParseIntError { kind: InvalidDigit })
Ok(7)
Err(ParseIntError { kind: InvalidDigit })
0
Parse error: invalid digit found in string
-1
Some(42)

Common Mistakes

Mistake 1: Using ? in a function with a void return type causes a compile error

The ? operator requires the function's return type to be Result (or Option). To use ? in main(), change its return type to Result<(), Box<dyn std::error::Error>>.

unwrap_mistake1.rs
use std::num::ParseIntError;

// ? cannot be used in a function that returns ().
fn parse_number(s: &str) {
    let n = s.parse::<i32>()?; // compile error
    println!("{}", n);
}

fn main() {
    parse_number("42");
}

Compile with the following command:

rustc unwrap_mistake1.rs
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option`

Change the function to return a Result type, or use match instead of ?.

unwrap_fix1.rs
use std::num::ParseIntError;

fn parse_number(s: &str) -> Result<(), ParseIntError> {
    let n = s.parse::<i32>()?;
    println!("{}", n);
    Ok(())
}

// To use ? in main, change its return type to Result.
fn main() -> Result<(), Box<dyn std::error::Error>> {
    parse_number("42")?;
    parse_number("99")?;
    Ok(())
}

Compile with the following command:

rustc unwrap_fix1.rs
./unwrap_fix1
42
99

Mistake 2: A vague expect() message makes debugging difficult

When using expect(), provide a specific message that will help with debugging if a panic occurs. A vague message like "should succeed" makes it hard to identify the cause.

unwrap_expect.rs
use std::env;

fn main() {
    // A vague message makes debugging difficult.
    // let port = env::var("PORT").expect("should succeed");

    // Provide a specific message, or use a fallback instead.
    let port = env::var("PORT").unwrap_or_else(|_| String::from("8080"));
    println!("PORT={}", port);

    // In test code, a clear expect() message is useful.
    let n = "42".parse::<i32>().expect("this is a compile-time constant and cannot fail to parse");
    println!("n={}", n);
}

Compile with the following command:

rustc unwrap_expect.rs
./unwrap_expect
PORT=8080
n=42

Notes

The ? operator is syntactic sugar introduced in Rust 1.13 that reduces manual error-propagation code using match to a single character. The ? operator can only be used when the function's return type is Result or Option. To use it in main(), you must change the return type to Result<(), Box<dyn std::error::Error>>.

When error type conversion is needed, ? automatically calls the From trait to convert the error type. If your custom error type has the appropriate From implementation, you can use ? consistently even in functions that mix different error types.

If you find any errors or copyright issues, please .