Rust unwrap() 和 expect() 方法
unwrap()
和expect()
方法:在 Rust 中,这些方法用于处理Option
和Result
类型,unwrap()
在遇到Err
或None
会触发 panic,而expect()
在触发 panic 时提供自定义消息。unwrap()
与expect()
的应用:这两种方法可用于简化从Option
或Result
类型中提取值的代码,避免编写复杂的match
表达式。但如果遇到错误值,它们会导致程序崩溃。- 问号运算符的使用:
?
运算符是Result
和Option
类型的简写形式,用于更简洁地处理错误。对于Result<T, E>
,如果值是Err(e)
,则立即返回Err()
;对于Option<T>
,如果值是None
,则返回None
。
unwrap()
和 expect()
是 Rust 中用于处理 Option 和 Result 类型的实用方法。
unwrap() 方法
在 Rust 中,unwrap 用于返回 Option
和 Result
枚举的操作结果。如果 unwrap 遇到错误 Err
或 None
,它将触发 panic 并停止程序执行。
unwrap 方法定义在 Option
和 Result
类型上。
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()
都给出了相同的输出。唯一的区别是,如果返回值是 None
,unwrap()
会触发 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()
方法在 Option
和 Result
类型上都有定义。
让我们将上面的示例更新为使用 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
返回 None
和 Result
返回 Err
的可能性不存在时将产生相同的结果。
注意: unwrap()
和 expect()
是用于处理 Option
和 Result
类型的实用方法。它使我们的程序更简洁,避免了编写冗长的 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
**注意:**问号运算符(?
)只能在返回 Result
或 Option
的函数中使用。