跳到主要内容

Rust unwrap() 和 expect() 方法

提示
  1. unwrap()expect() 方法:在 Rust 中,这些方法用于处理 OptionResult 类型,unwrap() 在遇到 ErrNone 会触发 panic,而 expect() 在触发 panic 时提供自定义消息。
  2. unwrap()expect() 的应用:这两种方法可用于简化从 OptionResult 类型中提取值的代码,避免编写复杂的 match 表达式。但如果遇到错误值,它们会导致程序崩溃。
  3. 问号运算符的使用? 运算符是 ResultOption 类型的简写形式,用于更简洁地处理错误。对于 Result<T, E>,如果值是 Err(e),则立即返回 Err();对于 Option<T>,如果值是 None,则返回 None

unwrap()expect() 是 Rust 中用于处理 Option 和 Result 类型的实用方法。

unwrap() 方法

在 Rust 中,unwrap 用于返回 OptionResult 枚举的操作结果。如果 unwrap 遇到错误 ErrNone,它将触发 panic 并停止程序执行。

unwrap 方法定义在 OptionResult 类型上。

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

示例:使用 match 表达式

// 通过用户名查找用户的函数,返回 Option 类型
fn get_user(username: &str) -> Option<&str> {
if username.is_empty() {
return None;
}

return Some(username);
}

fn main() {
// 返回一个 Option
let user_option = get_user("Hari");

// 使用 match 表达式从 Option 中获取结果
let result = match user_option {
Some(user) => user,
None => "未找到!",
};

// 打印结果
println!("user = {:?}", result);
}

输出

user = "Hari"

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

现在,这个程序可以使用 unwrap() 方法来替代较为繁琐的 match 表达式。

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

示例:使用 unwrap()

// 查找用户名对应用户的函数,返回 Option 枚举
fn get_user(username: &str) -> Option<&str> {
if username.is_empty() {
return None;
}

return Some(username);
}

fn main() {
// 使用 unwrap 方法从 get_user 函数获取 Option 枚举的结果
let result = get_user("Hari").unwrap();

// 打印结果
println!("user = {:?}", result);
}

输出

user = "Hari"

match 表达式和 unwrap() 都给出了相同的输出。唯一的区别是,如果返回值是 Noneunwrap() 会触发 panic。

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

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

这种情况下的输出将是,

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

expect() 方法

expect()unwrap() 非常相似,但增加了一个自定义的 panic 消息作为参数。

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

让我们将上面的示例更新为使用 expect() 而不是 unwrap()

// 通过用户名查找用户的函数,返回一个 Option 枚举
fn get_user(username: &str) -> Option<&str> {
if username.is_empty() {
return None;
}

return Some(username);
}

fn main() {
// 使用 expect 方法从 get_user 函数获取 Option 枚举的结果
let result = get_user("").expect("fetch user");

// 打印结果
println!("user = {:?}", result);
}

输出

线程 'main' 在 'fetch user', src/main.rs:12:31 处发生 panic

这里,我们使用 expect() 并将 panic 消息作为参数。

expect()unwrap()Option 返回 NoneResult 返回 Err 的可能性不存在时将产生相同的结果。

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

问号(?)运算符

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

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

  • 如果值是 Err(e),它将立即返回 Err()
  • 如果值是 Ok(x),它将解包并返回 x

让我们看一个示例。

use std::num::ParseIntError;

// 解析整数的函数
fn parse_int() -> Result<i32, ParseIntError> {
// ? 的示例,其中值被解包
let x: i32 = "12".parse()?; // x = 12

// ? 的示例,其中错误被立即返回
let y: i32 = "12a".parse()?; // 立即返回 Err()

Ok(x + y) // 不会执行到这一行
}

fn main() {
let res = parse_int();

println!("{:?}", res);
}

输出

Err(ParseIntError { kind: InvalidDigit })

这样,函数中的错误处理被简化为一行代码,使其更清晰易读。

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

  • 如果值是 None,则返回 None
  • 如果值是 Some(x),则解包值并返回 x

**注意:**问号运算符(?)只能在返回 ResultOption 的函数中使用。