尝试编写f32和f44上的泛型结构/impl。
我使用特征num_traits::float::Float
作为特征边界。
但是,当函数中使用具体值时,例如初始化数组或使用数组长度(usize(时,我会遇到编译器错误。想把混凝土类型铸造成通用T,还是什么??我该如何处理?
示例1:
pub struct RingArray<T: Float, const N: usize> {
tail: usize, // Index of the most recently added element
data: [T; N], // Array containing the data.
}
impl<T: Float, const N: usize> RingArray<T, N> {
/// Creates a new RingArray of with length `length` and initialized to `init_value`.
pub fn new() -> Self {
Self {
tail: N - 1, // raw index to the last element
// Initialize the data array to 0.0
data: [0.0; N], // <-- ERROR. Compiler complains here about 0.0. Expected type T found {float}
}
}
}
示例2:
pub struct MovingAverageFilter<T: Float, const N: usize> {
ring_array: RingArray<T, N>,
sum: T,
}
impl <T: Float, const N: usize> MovingAverageFilter<T, N> {
pub fn push(&mut self, input: T) -> T {
// Push the input and pop the head.
let head = self.ring_array.push(input);
// Add input to the sum and subtract the head
self.sum = self.sum + input - head;
let length = self.ring_array.len();
// Want to cast length to type T. How?
self.sum/length // <-- ERROR. Expectded denom to be type T, found usize
}
}
0.0
是一个不能在通用上下文中使用的文字。相反,您可以使用num_traits
中的Zero
,这是具有有意义的";零";值:
use num_traits::Zero;
pub fn new() -> Self {
Self {
tail: N - 1,
// Initialize the data array to 0.0
data: [Zero::zero(); N],
}
}
在第二部分中,您将尝试用usize
来划分泛型数字类型。您需要首先将usize
转换为float类型,可以通过在同一机箱中使用FromPrimitive
约束类型来实现:
use num_traits::FromPrimitive;
impl <T: Float + FromPrimitive, const N: usize> MovingAverageFilter<T, N> {
pub fn push(&mut self, input: T) -> T {
// Push the input and pop the head.
let head = self.ring_array.push(input);
// Add input to the sum and subtract the head
self.sum = self.sum + input - T::from_usize(head).unwrap();
let length = self.ring_array.len();
// Convert the usize to a T before dividing
self.sum / T::from_usize(length).unwrap()
}
}