我正在尝试编写一个将Integer
减半的泛型函数。为了记录,我知道有一个num_integer::Integer
特征,我在我的真实代码中使用它。
为了减半,我Integer
所需的唯一操作就是能够将引用移到右边和一个值。我想在很多地方使用Integer
,所以我在Integer
特征中捕获这两个特征并为其提供通用实现。但是,我仍然需要为std::ops::Shr
函数指定half
。
我知道这个问题有两种解决方法。一种是在任何地方指定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 :(得分: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()
}
}
这不是真正解决核心问题,但它确实可以让你避免再次编写那个绑定。