我正在尝试围绕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})
在我看来,两者都是相同的情况,但显然我错了。任何人都可以向我解释这个区别,并可能向我展示一个解决方案吗?
答案 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 Num
和f32
的{{1}}实施不是FromStrRadixErr = ParseFloatError
的原因。
并可能向我展示一个解决方案?
您说您正在尝试围绕ParseFloatError
构建通用包装器,但您的示例使用ParseIntError
std::<T>::from_str_radix
,因此您尝试在T::from_str_radix
周围编写包装器}。
一种选择是直接使用T: Num
和Num::from_str_radix
而不是创建包装器,最后,Num
是包装器。
也许您想将包装器限制为原始整数并使用FromStrRadixErr
。在这种情况下,您可以添加限制Num
:
ParseIntError