「関数型プログラミング」スタイルでコードを書きたいと思います。
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 (I' mrustc 1.49.0-nightly を使用 (ffa2e7ae8 2020-10-24))lines()
s を返しますResult
: https://doc.rust-lang.org/std/io/trait.BufRead.html#method.lines