2016-10-09 10 views
3

の場合、.max()は機能しませんので、引数がNaNではないことを示すForceOrd構造体を記述しています。しかし、私はエラーでコンパイルするInto特性の実装を取得することはできません制約付き構造体のFrom/Intoの実装

let m = xs.iter().map(|&x| ForceOrd(x)).max().unwrap().into(); 

:意図した使用法のようなものです

conflicting implementations of trait `std::convert::Into<_>` for type `ForceOrd<_>` 

コード(playground):

#[derive(PartialEq, PartialOrd)] 
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X); 
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { } 
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> { 
    fn cmp(&self, other: &Self) -> std::cmp::Ordering { 
     self.0.partial_cmp(&other.0).unwrap() 
    } 
} 
/// doesn't work 
impl<X: PartialEq + PartialOrd> Into<X> for ForceOrd<X> { 
    fn into(x: Self) -> X { x.0 } 
} 
/// doesn't work either 
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X { 
    fn from(x: ForceOrd<X>) -> Self { x.0 } 
} 
+0

これに一般的な制約を緩和し、f64で直接実装すると効果がありますか?それはあなたのための選択肢ではありませんか?あなたが持っているような箱の中のオープンジェネリックに特性境界を追加することは可能ではないと思います(_just_ 'From'を実装するとエラーになるはずです) –

答えて

5

FromIntoの両方を1つのタイプに実装することはできません。つまり、impl From<ForceOrd<X>> for Xもありますimpl Into<X> for ForceOrd<X>。あなたにも1つだけ必要です。 IntoFrom両方の状態のためのドキュメントとして:

​​

あなたはおそらくちょうどFrom実装して行く必要があります。編集When should I implement std::convert::From vs std::convert::Into?

:あなたは、一般的に選ぶことについては、次の質問を見ることができますが、これがいかに見ることができるの下Fromを実装するとして、(この場合は)ちょうどimpl Intoを削除するだけで、簡単ではありませんf64のために達成:

#[derive(PartialEq, PartialOrd, Debug)] 
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X); 

impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { } 

impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> { 
    fn cmp(&self, other: &Self) -> std::cmp::Ordering { 
     self.0.partial_cmp(&other.0).unwrap() 
    } 
} 

impl<X: PartialEq + PartialOrd> From<X> for ForceOrd<X> { 
    fn from(x: X) -> ForceOrd<X> { 
     ForceOrd(x) 
    } 
} 

fn main() { 
    let xs = vec![1.1f64, 3.5, 2.2]; 

    let max = xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap(); 

    println!("{:?}", max); // prints "ForceOrd(3.5)" 
} 

は、残念ながら、私は、これは限りあなたが得ることができるようになり怖いです。あなたは、実装することはできません。

impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X 

f64このクレートにローカルではないので、最終的な

<f64>::from(xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap()) 

を行うことができるように。この制限の詳細については、this very detailed blog entry by Niko Matsakisthis question in StackOverflowを参照してください。

+0

OPはそれぞれ個別に試しました。この問題は、ジェネリック型が現在のクレートで宣言されていない特性境界を持つ特性を実装しようとしています。私はこれが可能だとは思わない。元の特性が生きているので、標準ライブラリで可能です。 –

+1

「impl」が1つのみの場合の解決策で私の答えを広げました。 – ljedrz

関連する問題