Rust unwrap() 和 expect()

unwrap()expect() 是 Rust 中与 Option 和 Result 类型配合使用的实用方法。


unwrap() 方法

Rust 中的 Unwrap 方法会返回 OptionResult 枚举的操作结果。如果 unwrap 遇到错误 ErrNone,它将恐慌并停止程序执行。

Unwrap 方法定义在 OptionResult 类型上。

Option 枚举类型可以通过 match 表达式以及 unwrap() 来处理。

示例:使用 match 表达式

// function to find a user by their username which returns an Option type
fn get_user(username: &str) -> Option<&str> {
    if username.is_empty() {
        return None;
    }

    return Some(username);
}

fn main() {
    // returns an Option
    let user_option = get_user("Hari");

// use of match expression to get the result out of Option let result = match user_option { Some(user) => user, None => "not found!", };
// print the result println!("user = {:?}", result); }

输出

user = "Hari"

在这里,我们有一个名为 get_user 的函数,它返回一个 Option 类型。它可以返回 Some(&str)None

现在,这个程序可以使用 unwrap() 方法来摆脱稍微冗长的 match 表达式。

让我们在上面的示例中使用 unwrap()

示例:使用 unwrap()

// function to find a user by their username which return an Option enum
fn get_user(username: &str) -> Option<&str> {
    if username.is_empty() {
        return None;
    }

    return Some(username);
}

fn main() {
// use of unwrap method to get the result of Option enum from get_user function let result = get_user("Hari").unwrap();
// print the result println!("user = {:?}", result); }

输出

user = "Hari"

match 表达式和 unwrap() 都会产生相同的输出。唯一的区别是,如果返回值是 Noneunwrap() 会恐慌。

如果我们更新上面的程序,向 get_user() 方法发送一个空的用户名参数,它将恐慌。

let result = get_user("").unwrap();

在这种情况下,输出将是:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:12:31ßß

expect() 方法

expect()unwrap() 非常相似,只是它额外接受一个自定义的恐慌消息作为参数。

expect() 方法定义在 OptionResult 类型上。

让我们更新上面的示例,使用 expect() 代替 unwrap()

// function to find a user by their username which return an Option enum
fn get_user(username: &str) -> Option<&str> {
    if username.is_empty() {
        return None;
    }

    return Some(username);
}

fn main() {
// use of expect method to get the result of Option enum from get_user function let result = get_user("").expect("fetch user");
// print the result println!("user = {:?}", result); }

输出

thread 'main' panicked at 'fetch user', src/main.rs:12:31

在这里,我们将 expect() 与作为参数的恐慌消息一起使用。

如果 Option 没有返回 None 的可能性,或者 Result 没有返回 Err 的可能性,那么 expect()unwrap() 将产生相同的结果。

注意: unwrap()expect() 是处理 OptionResult 类型的实用方法。它们使我们的程序更简洁,并避免了编写冗长的 match 表达式来返回结果的需要。


问号 (?) 操作符

问号 (?) 操作符是返回 Result 的简写。它只能应用于 Result<T, E>Option<T> 类型。

当我们对 Result<T, E> 类型应用 ? 时:

  • 如果值为 Err(e),它会立即返回一个 Err()
  • 如果值为 Ok(x),它会解包并返回 x

让我们看一个例子。

use std::num::ParseIntError;

// Function to parse an integer
fn parse_int() -> Result<i32, ParseIntError> {
// Example of ? where value is unwrapped let x: i32 = "12".parse()?; // x = 12 // Example of ? where error is returned let y: i32 = "12a".parse()?; // returns an Err() immediately
Ok(x + y) // Doesn't reach this line } fn main() { let res = parse_int(); println!("{:?}", res); }

输出

Err(ParseIntError { kind: InvalidDigit })

这样,函数中的错误处理就减少到一行代码,使其更清晰、更易读。

同样,当我们对 Option<T> 类型应用 ? 时:

  • 如果值为 None,它将返回 None
  • 如果值为 Some(x),它会解包该值并返回 x

注意: 问号操作符 (?) 只能用于返回 ResultOption 的函数。

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战