2017-10-24 3 views
2

私はIntegerの半分の汎用関数を書こうとしています。記録のために、私はnum_integer::Integer特性があり、私はそれを私の実際のコードで使用していることを知っています。形質が実装されている型への参照に制限を課す可能性はありますか?

半分にするために、私のIntegerが必要とする操作は、右と1つの値への参照をシフトする機能です。私は多くの場所でIntegerを使用したいので、私はInteger形質でこれらの2つの特性を捕捉し、それに対する一般的な実装を提供します。しかし、私のhalf機能にはまだstd::ops::Shrを指定する必要があります。

この問題の2つの回避策を知っています。一つは、どこにでもstd::ops::Shrを指定することです:

extern crate num_traits; 

pub trait Integer 
where 
    Self: num_traits::One, 
    for<'a> &'a Self: std::ops::Shr<Self, Output = Self>, 
{ 
} 

impl<T> Integer for T 
where 
    T: num_traits::One, 
    for<'a> &'a T: std::ops::Shr<T, Output = T>, 
{ 
} 

fn half<N: Integer>(n: &N) -> N 
where 
    for<'a> &'a N: std::ops::Shr<N, Output = N>, // Would like to get rid of this line! 
{ 
    n >> num_traits::one() 
} 

fn main() { 
    println!("{}", half(&85)); 
} 

別のオプションは、halfがそれを借りるのではなく、その引数を消費することです、その場合には、私が代わりに参照の値をシフトすることだし、問題はラインがもはや必要ではありませんコメント:

extern crate num_traits; 

pub trait Integer 
where 
    Self: num_traits::One, 
    Self: std::ops::Shr<Self, Output = Self>, 
{ 
} 

impl<T> Integer for T 
where 
    T: num_traits::One, 
    T: std::ops::Shr<T, Output = T>, 
{ 
} 

fn half<N: Integer>(n: N) -> N { 
    n >> num_traits::one() 
} 

fn main() { 
    println!("{}", half(85)); 
} 

私が考慮していない他の選択肢はありますか?

+0

私は完全にはわかりませんが、[Implied bounds(RFC 2089)](https://github.com/rust-lang/rust/issues/44491)はこれを修正することになっています。 – Stefan

答えて

1

1つの選択肢は、形質メソッドに機能を移動するには、次のようになります。

pub trait Integer 
where 
    Self: num_traits::One, 
    for<'a> &'a Self: std::ops::Shr<Self, Output = Self>, 
{ 
    fn half(&self) -> Self { 
     self >> num_traits::one() 
    } 
} 

これは本当には、コアの問題を解決しませんが、それはあなたがまだ別の時間を拘束書き込みを避けることができません。

関連する問題