繁体   English   中英

是否可以在 Rust 中编写通用整数长度函数?

[英]Is it possible to write a generic integer length function in Rust?

我为u32编写了一个长度函数。 我可以轻松地复制/粘贴/编辑到其他 int 类型,但是当我尝试使用泛型时,我陷入了困境。 有我误解的概念吗?

传递长度函数

fn len_int(n: u32) -> u32 { // 0
    std::iter::repeat_with({
        let mut l = 0;
        // can't call pow on ambiguous numeric type
        move || match n / 10u32.pow(l) { // 1
            0 => 0,
            _ => {
                l += 1;
                1
            }
        }
    })
        .take_while(|&x| x != 0)
        // count returns usize
        .count() as u32 // 2
}

失败的通用长度函数:I

fn len_int<T>(n: T) -> T
where
    T: Copy + Clone,
{
    std::iter::repeat_with({
        let mut l = 0;
        move || match n / 10.pow(l) {
            //1
            0 => 0,
            _ => {
                l += 1;
                1
            }
        }
    })
    .take_while(|&x| x != 0)
    .count() at T // 2
}

编译器告诉我,我不能call method pow on ambiguous numeric type {integer} cannot divide T by type error或转换count()在具有端部as T ,因为T是不是原始类型。 操场

您可能有特定的类型,但编译器不知道。 对于编译器,泛型类型T可以是任何东西 它可以是一个字符串。 它可以是对函数指针的引用。 它可以是文件句柄的向量。 任何东西 因此,它需要您的代码同时使用所有这些可能的类型。

为了更具体的工种,必须提前申报你想要的类型,支持时间的一切 编译器不会让你使用任何你没有声明的操作。

Rust 的标准库中没有.pow的特性,所以你不能开箱即.pow声明它。 你可以自己做一个,或者使用num-traits

我们可以定义一个特征,然后为您想要在泛型函数中支持的具体类型实现特征:

pub trait IntLenExt<T> {
    fn is_divis(&self, power: u32) -> bool;
    fn cast_count(count: usize) -> T;
}

impl IntLenExt<u32> for u32 {
    fn is_divis(&self, power: u32) -> bool {
        self / 10u32.pow(power) == 0
    }

    fn cast_count(count: usize) -> u32 {
        count as u32
    }
}

impl IntLenExt<u64> for u64 {
    fn is_divis(&self, power: u32) -> bool {
        self / 10u64.pow(power) == 0
    }

    fn cast_count(count: usize) -> u64 {
        count as u64
    }
}

fn len_int<T>(n: T) -> T
where
    T: Copy + Clone + IntLenExt<T>,
{
    T::cast_count(std::iter::repeat_with({
        let mut l = 0;
        move || match n.is_divis(l) {
            //1
            true => 0,
            false => {
                l += 1;
                1
            }
        }
    })
    .take_while(|&x| x != 0)
    .count()) // 2
}


fn main() {
    let input: u64 = 100;
    println!("len_int({}) => {}", input, len_int(input));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM