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
的函数。