【发布时间】:2018-02-26 22:21:49
【问题描述】:
我有一系列几乎相同的函数,只是类型和常数不同。例如:
fn update16(table: &[u16], init: u16, xs: &[u8]) -> u16 {
xs.iter().fold(init, |acc, x| { (acc << 8) ^ table[(((acc >> 8) as u8) ^ x) as usize] })
}
fn update32(table: &[u32], init: u32, xs: &[u8]) -> u32 {
xs.iter().fold(init, |acc, x| { (acc << 8) ^ table[(((acc >> 24) as u8) ^ x) as usize] })
}
所以我考虑让这个函数在类型上通用:
trait Update<T> {
fn update(table: &[T], init: T, xs: &[u8]) -> T;
}
我最终能够实现这个:
use std::ops::Shl;
use std::ops::Shr;
use std::ops::BitXor;
use std::mem::size_of;
extern crate num;
use num::ToPrimitive;
struct Normal;
impl<
T: Copy + Shl<u8, Output = T> + Shr<usize, Output = T> + BitXor<Output = T> + ToPrimitive,
> CrcUpdate<T> for Normal {
fn update(table: &[T], init: T, xs: &[u8]) -> T {
xs.iter().fold(init, |acc, x| {
(acc << 8) ^
table[(ToPrimitive::to_u8(&(acc >> ((8 * size_of::<T>()) - 8))).unwrap() ^ x) as
usize]
})
}
}
这比我预期的要复杂得多。我不得不使用一堆特征,定义一个空结构,包含一个外部 crate 并在某种程度上模糊了基本计算。它肯定比原来的要多得多。
这是在 Rust 中为整数使用泛型的正确方法吗?还是我错过了一种更简单的方法来解决这个问题?
【问题讨论】: