map で Result を引き回すときに Err を意識したくない その2
   1 min read

その1はこちらです:

その1では戻り値が i * 2i32 型になる話でしたが、その次に考えたかったのは Result が返ってくるメソッドで引き回すときの話でした。こんな感じで:

// and_then を利用すれば可能だが
// この and_then を省きたい

use anyhow::{anyhow, Result};

fn parse(s: &str) -> Result<i32> {
    let res = s.parse::<i32>()?;
    Ok(res)
}

fn x2(i: i32) -> Result<i32> {
    if i < 50 {
        Ok(i * 2)
    } else {
        Err(anyhow!("too large"))
    }
}

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let numbers: Vec<_> = strings
        .into_iter()
        .map(parse)
        .map(|r| r.and_then(x2))
        .map(|r| r.and_then(x2))
        .collect();
    println!("Results: {:?}", numbers);
    // Results: [Err(invalid digit found in string), Err(too large), Ok(72)]
}

anyhow::Result<i32> な関数を map でつなげて、最終的な結果を anyhow::Result<i32> のベクタで得たかったのです。

なんとなくその1の結果からするにイテレータを自作すれば良さそうに思われるのですが、現時点では 実装がさっぱり理解できないので、将来の自分に任せたいと思います…