【问题标题】:Creating a generic function bounded to integer types创建一个绑定到整数类型的泛型函数
【发布时间】:2019-11-08 22:05:43
【问题描述】:

在我尝试学习 rust 的过程中,我从一些基本练习开始。 我写了一个简单的函数,我希望是惯用的 rust 来计算整数中设置的位数。

fn bit_count(x: u32) -> u32 {
    (0..32).into_iter().map(|i| (x >> i) & 1).sum()
}

fn main() {
    println!("{} has {} set bits.", 5, bit_count(5));
}

现在我想让函数通用化,这样我就可以传递任何整数类型:i32u32i64u64...等。

我对 c++ 中的 tmp 非常熟悉,但是我尝试使用 rust 泛型失败了,到目前为止我有这个:

extern crate num;

fn bit_count<T>(x: T) -> T
where
    T: num::Integer + std::ops::BitAnd + std::ops::Shr + num::NumCast,
    std::ops::Range<T>: std::iter::IntoIterator,
{
    (T::zero()..num::NumCast::from(32).unwrap())
        .into_iter()
        .map(|i| (x >> num::NumCast::from(i)) & T::one())
        .sum()
}

fn main() {
    println!("{} has {} set bits.", 5, bit_count(5));
}

我看到广告中的 num 板条箱看起来很合适。我期待拥有T: num::Integer 并完成,但我觉得我在这里螺旋式下降,我似乎无法获得正确的边界组合。

任何建议都会很棒!并且任何使我的代码更惯用的技巧也会有所帮助,谢谢。

【问题讨论】:

    标签: generics rust traits


    【解决方案1】:

    终于到了。结果我需要使用num::PrimInt trait 作为我的界限,因为它包含所有的按位操作和强制转换。 num::Integer 的约束较少,并且在纯数学意义上对整数进行建模,因此没有按位运算。

    我的最终代码如下所示:

    extern crate num;
    
    fn bit_count<T>(x: T) -> T
    where
        T: num::PrimInt + std::iter::Sum,
    {    
        let n_bits = std::mem::size_of::<T>() * u8::BITS as usize;
        (0..n_bits).into_iter().map(|i| (x >> i) & T::one()).sum()
    
    }
    
    fn main() {
        println!("{} has {} set bits.", 5, bit_count(5u32));
        println!("{} has {} set bits.", 5, bit_count(5i32));
        println!("{} has {} set bits.", 5, bit_count(5i64));
    }
    

    不需要T::one() 会很好,但似乎没有办法解决它。此外,在我的范围内需要 std::iter::Sum 特征以允许功能工作流。

    num crate 实际上也有一个函数来计算设置位的数量num::PrimInt::count_ones

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多