简体   繁体   English

如何为某些泛型类型实现泛型特征的默认实现?

[英]How can I implement a default implementation of a generic trait for some generic type?

I want to implement a default implementation of a trait MovingAverage over some generic type Vec<T> , but I'm obviously doing something wrong since I can make it work for the concrete type Vec<f64> but not for the concrete type Vec<i32> .我想在一些泛型类型Vec<T>上实现特征MovingAverage的默认实现,但我显然做错了,因为我可以使它适用于具体类型Vec<f64>但不适用于具体类型Vec<i32> . Here's the output from the error:这是错误中的 output :

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`

Here's my code from ma.rs:这是我来自 mar.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
    }
}

My main.rs我的 main.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 

What's going on in my error, and what would be the proper way to go about implementing a trait over a generic type without having to implement the trait for each concrete type?我的错误发生了什么,go 关于在泛型类型上实现特征而不必为每个具体类型实现特征的正确方法是什么? Thanks in advance, and kindly let me know if you need any further clarification.提前致谢,如果您需要任何进一步的说明,请告诉我。

Maybe a better bound would be T: Into<f64> .也许更好的界限是T: Into<f64> Then you can simply convert each element into a f64 when you access it.然后,您可以在访问每个元素时简单地将其转换为f64 Also, if you implement the trait for [T] instead of Vec<T> , it will also work for slices.此外,如果您为[T]而不是Vec<T>实现特征,它也适用于切片。 Try this:尝试这个:

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
    }
}

Playground 操场

(Side note: I think your code may unintentionally ignore the last element of the input) (旁注:我认为您的代码可能会无意中忽略输入的最后一个元素)

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

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