2016-05-25 2 views
4

std::<T>::from_str_radixの周りに汎用ラッパーを構築しようとしています。ドキュメントによれば、from_str_radixResult<T, ParseIntError>を返します。しかしFromStrRadixErrをParseIntErrorに変換する方法?

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

がコンパイルされません。一方

error: mismatched types: expected core::result::Result<T, core::num::ParseIntError> , found core::result::Result<T, <T as num_traits::Num>::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) 
} 

は罰金コンパイルし、私の心に予想される結果

Err(ParseIntError { kind: Overflow })

を印刷します、どちらも同じ状況ですが、obviouうーん、私は間違っている。誰も私にその違いを説明し、解決策を提示することはできますか?

+1

を、最初のコンパイルエラーは'エラーです:解決に失敗しました。宣言されていない型またはモジュール 'num_traits'の使用[E0433]' – EdoPut

+0

'num_traits'という名前の木枠からの型を取り出しています。ただし、部分的に実装をコピーできます。詳細については、https://play.rust-lang.org/?gist=0b7a2c5790e1c344a76663cc767f8790&version=stable&backtrace=0を参照してください。 –

答えて

2

How to convert FromStrRadixErr to ParseIntError ?

これはできません。 io::Errorのようないくつかのエラーでは、原因となるエラーでインスタンスを作成できるため、別のエラーをラップするエラーを作成できます。 ParseIntErrorにこのような機能がある場合は、FromStrRadixErrというエラーの原因でParseIntErrorが作成される可能性がありますが、ParseIntErrorでは発生しません。

Can anybody explain to me the difference?

このコード:T::from_str_radixの返される型がResult<T, FromStrRadixErr>Result<T, ParseIntError>ではないので

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

はコンパイルされません。戻り値の型を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) 
} 

u8definesFromStrRadixErr = ParseIntErrorためNum形質実装ので細かいコンパイルします。

あなたはf32u8を変更する場合:

それがコンパイルに失敗します。 の実装がf32definesFromStrRadixErr = ParseFloatErrorおよびParseFloatErrorでない理由は、ParseIntErrorではありません。

and possibly show me a solution?

あなたはstd::<T>::from_str_radix汎用ラッパーを構築しようとしているが、あなたの例はT::from_str_radixどこT: Numを使用するので、あなたはNum::from_str_radixのラッパーを作成しようとしていると述べました。

1つのオプションは、最終的にラッパーを作成する代わりにNumFromStrRadixErrを使用することです。最後にNumがラッパーです。

ラッパーをプリミティブな整数に制限し、ParseIntErrorを使用したいことがあります。この場合は、あなたが制限FromStrRadixErr = ParseIntError追加することができます:あなたは `num_traits :: Num`形質を取得しようとしているところから追加してください

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

ありがとうmalbarbo。 _defined_であるタイプについてのヒントは、欠落していたリンクです。そして、私はそれを必要とする構文を推測したことはありません。 – stefan322935

+0

これは私が興味を持っているので、すでに 'T:num :: traits :: PrimInt'という制限を試していましたが、あなたの提案はうまく動作します:-) – stefan322935

関連する問題