不使用match,是否有可能将Option<Result<T, E>>转换为Result<Option<T>, E>?

28

我的第一反应是对Option进行映射,但我无法在闭包内部使用try!。这个match语句看起来有点多余,但我无法想出如何简化它。

fn example<T, E>(val: Option<Result<T, E>>) -> Result<Option<T>, E> {
    Ok(match val {
        Some(v) => Some(v?),
        None => None
    })
}
2个回答

28

在Rust 1.33中,transpose()已经稳定,所以你可以直接调用它:

fn main() {
    let x: Result<Option<i32>, ()> = Ok(Some(5));
    let y: Option<Result<i32, ()>> = Some(Ok(5));
    assert_eq!(x, y.transpose());
}

8
你可以使用 Option::map_or() 方法:
val.map_or(Ok(None), |v| v.map(Some))

6
val.map(|v| v.map(Ok)).unwrap_or_else(|e| Some(Err(e))) 可以实现相反的效果。 - Arnavion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接