处理嵌套.map()
闭Result
包
如果我们有一个inside a.map()
怎么办?.map()
.map()
.map()
这是嵌套操作的特定情况的示例。它解决的问题是如何从最里面的闭包传播失败,同时避免使用.unwrap()
哪个中止应用程序。
这种方法还可以?
在发生错误时在外层使用语法来捕获错误,或者如果没有发生错误,则解包结果以分配给变量。?
否则不能从闭包内部使用。
.parse()
因为它在下面使用将返回Result<T, ParseIntError>
。
use std::error::Error;
const DATA: &str = "1 2 3 4\n5 6 7 8";
fn main() -> Result<(), Box<dyn Error>>
{
let data = DATA.lines().map(|l| l.split_whitespace()
.map(|n| n.parse() /* can fail */)
.collect())
.collect::<Result<Vec<Vec<i32>>, _>>()?;
println!("{:?}", data);
Ok(())
}
请注意,外部.collect::<..>()
泛型表达式指定Result<Vec<Vec<..>>
. 内部.collect()
将生成Result
s,外部将其剥离,Result
因为它获取Ok
内容并生成 2-D 向量。
在不严重依赖类型推断的情况下,内部.collect()
泛型表达式将如下所示:
.collect::<Result<Vec<i32>, _>>()) // <--- Inner.
.collect::<Result<Vec<Vec<i32>>, _>>()?; // <--- Outer.
使用?
语法,变量 ,data
将被分配这个二维向量;否则该main()
函数将返回源自内部闭包的解析错误。
输出:
[[1, 2, 3, 4], [5, 6, 7, 8]]
更进一步,可以通过这种方式处理嵌套三层深度的解析结果。
type Vec3D<T, E> = Result<Vec<Vec<Vec<T>>>, E>;
const DATA: &str = "1 2 | 3 4\n5 6 | 7 8";
fn main() -> Result<(), Box<dyn Error>>
{
let data = DATA.lines()
.map(|a| a.split("|")
.map(|b| b.split_whitespace()
.map(|c| c.parse()) // <---
.collect())
.collect())
.collect::<Vec3D<i32,_>>()?;
println!("{:?}", data);
Ok(())
}
输出:
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
或者如果无法解析一个数字,我们会得到:
Error: ParseIntError { kind: InvalidDigit }