【问题标题】:How to idiomatically convert from Option<T> to Result<T, ()>?如何习惯性地将 Option<T> 转换为 Result<T, ()>?
【发布时间】:2020-04-19 04:10:20
【问题描述】:

我是 Rust 新手!从Option&lt;T&gt; 转换为Result&lt;T, ()&gt; 的最佳方法是什么?

TryFrom 特征似乎很普遍并返回一个结果。流行的 num_traits 的 NumCast 有很多转换,但它们都返回 Option&lt;T&gt;。类似地,像 Rust 标准库 中的 NonZeroI32 这样的 NonZero* 构造函数也是如此。然后我注意到 NumCast 实现了一个 from(),它返回一个 Option&lt;T&gt;,所以我想它可能有一种非标准的做事方式,但后来我看到了 NonZero* 实现并质疑这个想法。

无论如何,从选项转换为结果似乎很频繁,我还没有找到一个简洁的方法来做。例如:

/// Add common conversion from an i32 to a non-zero i32.
impl TryFrom<Container<i32>> for Container<NonZeroI32> {
  type Error = ();
  fn try_from(container: Container<i32>) -> Result<Self, ()> {
    // NonZeroI32::new() returns an Option not a Result. Try a helper.
    Ok(Self(option_to_result(NonZeroI32::new(container.0))?))
  }
}

/// Helper function to convert from an Option to a Result (both types are
/// foreign and so is From).
fn option_to_result<T>(option: Option<T>) -> Result<T, ()> {
  if let Some(some) = option {
    Ok(some)
  } else {
    Err(())
  }
}
/// Add another common conversion from an i32 to an i16.
impl TryFrom<Container<i32>> for Container<i16> {
  type Error = ();
  fn try_from(container: Container<i32>) -> Result<Self, ()> {
    // NumCast::from() also returns an Option not a Result. Try map_or() instead
    // of the helper.
    Ok(Self(NumCast::from(container.0).map_or(Err(()), |x| Ok(x))?))
  }
}

(上面的例子在Rust Playground。)

这些 NumCast、NonZero* 和 TryFrom 转换似乎很常见,但我的方法感觉很笨拙,就好像我将 Option 和 Result 类型相互对立一样。我在这些转换中苦苦挣扎,也错过了Option 类型的基本点,因为Result&lt;T,()&gt; 感觉相似。

那么,在 Rust 2018 中将 Option&lt;T&gt; 转换为 Result&lt;T,()&gt; 的惯用方法是什么?

【问题讨论】:

    标签: rust


    【解决方案1】:

    Option 具有 ok_or 方法,可用于此目的(好吧,事实上,对于更广泛的情况,但您的要求也适合这里):

    fn option_to_result<T>(option: Option<T>) -> Result<T, ()> {
      option.ok_or(())
    }
    

    Modified playground

    【讨论】:

    • 谢谢!我不知道我是怎么错过的,但现在很容易找到!
    猜你喜欢
    • 2019-05-23
    • 1970-01-01
    • 2021-05-05
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多