[英]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.