我想在一些泛型类型Vec<T>
上实现特征MovingAverage
的默认实现,但我显然做错了,因为我可以使它适用于具体类型Vec<f64>
,但不适用于具体的类型Vec<i32>
。以下是错误的输出:
error[E0599]: the method `sma` exists for struct `Vec<{integer}>`, but its trait bounds were not satisfied
--> src/main.rs:8:22
|
8 | let smai = numsi.sma(n);
| ^^^ method cannot be called on `Vec<{integer}>` due to unsatisfied trait bounds
|
::: /home/czar/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:397:1
|
397 | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| ------------------------------------------------------------------------------------------------ doesn't satisfy `Vec<{integer}>: MovingAverage`
|
= note: the following trait bounds were not satisfied:
`f64: AddAssign<{integer}>`
which is required by `Vec<{integer}>: MovingAverage`
`f64: SubAssign<{integer}>`
which is required by `Vec<{integer}>: MovingAverage`
这是我在ma.rs:中的代码
pub trait MovingAverage<Output = Vec<f64>> {
fn sma(&self, periods: usize) -> Output;
}
impl<T> MovingAverage for Vec<T>
where
T: Copy + Num,
f64: AddAssign<T> + SubAssign<T>,
{
fn sma(&self, periods: usize) -> Vec<f64> {
let mut sum = 0f64;
let mut ma = Vec::<f64>::new();
for i in 0..self.len() {
if i >= periods {
ma.push(sum / periods as f64);
sum -= self[i - periods];
}
sum += self[i];
}
ma
}
}
我的主.rs
let numsf = vec![5., 10., 3., 9., 8., 7.];
let mut numsi = vec![2, 4, 3, 5, 1, 1];
let n = 2;
let smaf = numsf.sma(n);
let smai = numsi.sma(n); // doesnt work here
我的错误是怎么回事?在不必为每个具体类型实现特性的情况下,在泛型类型上实现特性的正确方法是什么?提前谢谢,如果你需要进一步澄清,请告诉我。
也许T: Into<f64>
是一个更好的界限。然后,当你访问每个元素时,你可以简单地将其转换为f64
。此外,如果你为[T]
而不是Vec<T>
实现trait,它也适用于切片。试试这个:
impl<T: Copy + Into<f64>> MovingAverage for [T] {
fn sma(&self, periods: usize) -> Vec<f64> {
let mut sum = 0f64;
let mut ma = Vec::<f64>::new();
for i in 0..self.len() {
if i >= periods {
ma.push(sum / periods as f64);
sum -= self[i - periods].into();
}
sum += self[i].into();
}
ma
}
}
游乐场
(旁注:我认为您的代码可能会无意中忽略输入的最后一个元素(