我想以“函数式编程”风格编写一些代码。
但是,我从结果迭代器开始,我只想将函数应用于Ok
项目。此外,我想在第一个错误上停止迭代(但是,我愿意接受不同的行为)。
到目前为止,我使用的是嵌套map()
模式:<iter>.map(|l| l.map(replace))
. 我认为这是非常丑陋的。
使用每晚的“result_flattening”,我可以将每个嵌套Result<Result<T, E>, E>
的Result<T, E>
. 使用eyre::Context
我将不同的错误类型转换为eyre::Report
错误类型。所有这些都让人感觉很笨拙。
用 Rust 写这个的优雅方式是什么?
最小的工作示例
#![feature(result_flattening)]
use std::io::BufRead;
use eyre::Context;
fn main() {
let data = std::io::Cursor::new(b"FFBFFFBLLL\nBFBFBBFRLR\nFFFBFFBLLL");
let seats: Result<Vec<_>, _> = data
.lines()
.map(|l| l.map(replace).context("force eyre"))
.map(|l| l.map(|s| u32::from_str_radix(&s, 2).context("force eyre")))
.map(|r| r.flatten())
.collect();
println!("{:#?}", seats);
}
fn replace(line: String) -> String {
line.replace('F', "0")
.replace('B', "1")
.replace('L', "0")
.replace('R', "1")
}
进一步参考:
- 当 Iterator::map 返回 Result::Err 时,如何停止迭代并返回错误?
- 结果实现
FromIter
。 result_flatten
:https ://doc.rust-lang.org/std/result/enum.Result.html?search=#method.flatten ,https ://github.com/rust-lang/rust/issues/70142 (我' m 使用 rustc 1.49.0-nightly (ffa2e7ae8 2020-10-24))lines()
返回Result
s: https ://doc.rust-lang.org/std/io/trait.BufRead.html#method.lines