unwrap() 和 expect() 是 Rust 中与 Option 和 Result 类型配合使用的实用方法。
unwrap() 方法
Rust 中的 Unwrap 方法会返回 Option 和 Result 枚举的操作结果。如果 unwrap 遇到错误 Err 或 None,它将恐慌并停止程序执行。
Unwrap 方法定义在 Option 和 Result 类型上。
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() 都会产生相同的输出。唯一的区别是,如果返回值是 None,unwrap() 会恐慌。
如果我们更新上面的程序,向 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() 方法定义在 Option 和 Result 类型上。
让我们更新上面的示例,使用 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() 是处理 Option 和 Result 类型的实用方法。它们使我们的程序更简洁,并避免了编写冗长的 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。
注意: 问号操作符 (?) 只能用于返回 Result 或 Option 的函数。