如何惯用地从 Option<T> 转换为 Result<T, ()>?

Ste*_*ski 2 rust

我是 Rust 新手!从 an 转换Option<T>为 a的最佳方法是Result<T, ()>什么?

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

无论如何,从选项到结果的转换似乎很频繁,我还没有找到一种巧妙的方法。例如:

/// 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(())
  }
}
Run Code Online (Sandbox Code Playgroud)
/// 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))?))
  }
}
Run Code Online (Sandbox Code Playgroud)

(以上例子在Rust Playground 中。)

这些 NumCast、NonZero* 和 TryFrom 转换似乎很常见,但我的方法感觉很笨拙,好像我将 Option 和 Result 类型相互对抗。我在这些转换中挣扎,也错过了Option给定Result<T,()>感觉相似的类型的基本点。

那么,在 Rust 2018 中将an 转换为Option<T>to的惯用方法是Result<T,()>什么?