我是Rust的新手!将Option<T>
转换为Result<T, ()>
的最佳方法是什么?
TryFrom特性似乎很普遍并返回一个Result。流行的num_traits' NumCast有许多转换,但它们都返回一个Option<T>
。同样,像Rust标准库中的NonZeroI32这样的NonZero*构造函数也是如此。然后我注意到NumCast实现了一个返回Option<T>
的from()
,所以我认为它可能在一般情况下有一种非标准的做法,但接着我看到了NonZero*的实现,对那个想法产生了疑问。
无论如何,从Options转换为Results似乎很频繁,但我还没有找到一个简洁的方法。例如:
/// 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类型相互对抗。我在这些转换中挣扎,并且也错过了给定Result<T>感觉相似的Option类型的基本要点。
那么,在Rust 2018中将Option<T>转换为Result<T,()>的惯用方法是什么?