各种错误类型
有时 Option
需要和 Result
进行交互,或是 Result<T, Error1>
需要和 Result<T, Error2
进行交互。在这类情况下,我们想要以一种方式来管理不同的错误类型,使得它们可组合且易于交互。
使用组合算子的知识,我们能够重写上述代码来显式地处理错误。为了做到两种错误类型都能够出现,我们需要将他们转换为一种通用类型,比如 String
类型。
type Result<T> = std::result::Result<T, String>;
fn double_first(vec: Vec<&str>) -> Result<i32> {
vec.first()
// 若值存在则将 `Option` 转换成 `Result`。
// 否则提供一个包含该字符串(`String`) 的 `Err`。
.ok_or("Please use a vector with at least one element.".to_owned())
// 回想一下,`parse` 返回一个 `Result<T, ParseIntError>`。
// 映射任意错误 `parse` 产生得到 `String`。
// (原文:Map any errors `parse` yields to `String`.)
.map_err(|e| e.to_string())
// `Result<T, String>` 成为新的返回类型,
// 我们可以给里面的数字扩大两倍。
.map(|i| 2 * i))
}
fn print(result: Result<i32>) {
match result {
Err(e) => println!("Error: {}", e),
}
}
fn main() {
let empty = vec![];
let strings = vec!["tofu", "93", "18"];
print(double_first(empty));
print(double_first(strings));
在下一节,我们将学到一个替代方法来显式处理这型错误。