如何为泛型类型 Vec<T> 的向量实现特征?

Gre*_*reg 2 generics syntax traits rust

如何为泛型类型的向量实现以下特征Vec<T>

例如,如何以Difference通用方式实现以下(工作)特征(例如,使其对Vec<i32>, Vec<f32>,有效Vec<f64>)?

trait Difference {
    fn diff(&self) -> Vec<f64>;
}

impl Difference for Vec<f64> {
    fn diff(&self) -> Vec<f64> {
        self.windows(2)
            .map(|slice| (slice[0] - slice[1]))
            .collect()
    }
}

fn main() {
    let vector = vec![1.025_f64, 1.028, 1.03, 1.05, 1.051];
    println!("{:?}", vector.diff());
}
Run Code Online (Sandbox Code Playgroud)

从查看文档来看,它似乎应该是这样的:

trait Difference<Vec<T>> {
    fn diff(&self) -> Vec<T>;
}

impl Difference for Vec<T> {
    fn diff(&self) -> Vec<T> {
        self.windows(2)
            .map(|slice| (slice[0] - slice[1]))
            .collect()
    }
}

fn main() {
    let vector = vec![1.025_f64, 1.028, 1.03, 1.05, 1.051];
    println!("{:?}", vector.diff());
}
Run Code Online (Sandbox Code Playgroud)

但是上面的结果是:

trait Difference {
    fn diff(&self) -> Vec<f64>;
}

impl Difference for Vec<f64> {
    fn diff(&self) -> Vec<f64> {
        self.windows(2)
            .map(|slice| (slice[0] - slice[1]))
            .collect()
    }
}

fn main() {
    let vector = vec![1.025_f64, 1.028, 1.03, 1.05, 1.051];
    println!("{:?}", vector.diff());
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一些其他变体,但是所有变体都导致了更长的错误消息。

She*_*ter 5

正确的语法是:

trait Difference<T> { /* ... */ }

impl<T> Difference<T> for Vec<T> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

然后你需要要求T实现减法:

trait Difference<T> { /* ... */ }

impl<T> Difference<T> for Vec<T> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

并且您可以复制这些值:

error[E0369]: binary operation `-` cannot be applied to type `T`
 --> src/main.rs:9:26
  |
9 |             .map(|slice| (slice[0] - slice[1]))
  |                          ^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `T` might need a bound for `std::ops::Sub`
Run Code Online (Sandbox Code Playgroud)
impl<T> Difference<T> for Vec<T>
where
    T: std::ops::Sub<Output = T> + Copy,
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

或者T可以减去对的引用:

impl<T> Difference<T> for Vec<T>
where
    for<'a> &'a T: std::ops::Sub<Output = T>,
{
    fn diff(&self) -> Vec<T> {
        self.windows(2)
            .map(|slice| &slice[0] - &slice[1])
            .collect()
    }
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: