如何将FromStrRadixErr转换为ParseIntError?

时间:2016-05-25 07:25:08

标签: error-handling rust

我正在尝试围绕fn do_something<V, M>(/* some arguments */) -> /* ... */ where (V, M): VertexMaterialPair, { /* ... */ } 构建一个通用包装器。根据文档,std::<T>::from_str_radix会返回from_str_radix。但是

Result<T, ParseIntError>

不会编译:

  

错误:类型不匹配:预期fn foo<T: num_traits::Num>() -> Result<T, std::num::ParseIntError> { T::from_str_radix("4242", 10) } ,       找到core::result::Result<T, core::num::ParseIntError>

另一方面,这个

core::result::Result<T, <T as num_traits::Num>::FromStrRadixErr>

编译好并打印预期结果

  

Err(ParseIntError {kind:Overflow})

在我看来,两者都是相同的情况,但显然我错了。任何人都可以向我解释这个区别,并可能向我展示一个解决方案吗?

1 个答案:

答案 0 :(得分:3)

  

如何将FromStrRadixErr转换为ParseIntError

这是不可能的。某些错误(如io::Error)允许您创建具有导致错误的实例,因此您可以创建包含其他错误的错误。如果ParseIntError具有此类功能,您可以创建由ParseIntError错误导致的FromStrRadixErr,但ParseIntError则不会。

  

有人可以向我解释一下这个区别吗?

此代码:

fn foo<T: num_traits::Num>() -> Result<T, std::num::ParseIntError> {
    T::from_str_radix("4242", 10)
}

无法编译,因为返回的T::from_str_radix类型为Result<T, FromStrRadixErr>而不是Result<T, ParseIntError>。将返回类型(如您所做)更改为Result<T, FromStrRadixErr>,可以解决问题。

此代码:

fn main() {
    let x: Result<u8, std::num::ParseIntError> = foo();
    println!("{:?}", x);
}

fn foo<T: num_traits::Num>() -> Result<T, <T as num_traits::Num>::FromStrRadixErr> {
    T::from_str_radix("4242", 10)
}

编译正常,因为Num defines u8的{​​{1}}特征实施。

如果您将FromStrRadixErr = ParseIntError更改为u8

f32

无法编译。 let x: Result<f32, std::num::ParseIntError> = foo(); defines Numf32的{​​{1}}实施不是FromStrRadixErr = ParseFloatError的原因。

  

并可能向我展示一个解决方案?

您说您正在尝试围绕ParseFloatError构建通用包装器,但您的示例使用ParseIntError std::<T>::from_str_radix,因此您尝试在T::from_str_radix周围编写包装器}。

一种选择是直接使用T: NumNum::from_str_radix而不是创建包装器,最后,Num是包装器。

也许您想将包装器限制为原始整数并使用FromStrRadixErr。在这种情况下,您可以添加限制Num

ParseIntError