简体   繁体   English

在Rust中使用Trait的通用类型不匹配

[英]Generic Type Mismatch using Trait in Rust

I am doing a matrix addition using traits. 我正在使用特征进行矩阵加法。 I am stuck by the generic type mismatch. 我被通用类型不匹配所困扰。 My code is as following: 我的代码如下:

use std::{ops, fmt};

#[derive(PartialEq, Debug)]
pub struct Matrix<T> {
    data: Vec<T>,
    row: usize,
    col: usize,
}

impl<T: Copy> Matrix<T> {
    /// Creates a new matrix of `row` rows and `col` columns, and initializes
    /// the matrix with the elements in `values` in row-major order.
    pub fn new(row: usize, col: usize, values: &[T]) -> Matrix<T> {
        Matrix {
            data: values.to_vec(), // make copy and convert &[T] to vector type
            row: row,
            col: col,
        }
    }
}

impl<T: ops::Add<Output = T> + Copy> ops::Add for Matrix<T> {
    type Output = Self;

    /// Returns the sum of `self` and `rhs`. If `self.row != rhs.row || self.col != rhs.col`, panic.
    fn add(self, rhs: Self) -> Self::Output {

        assert!(self.col == rhs.col);
        assert!(self.row == rhs.row);

        let mut newdata = Vec::new(); // make a new vector to store result
        let mut sum: i32; // temp variable to record each addition

        for num1 in self.data.iter() {
            for num2 in rhs.data.iter() {
                sum = *num1 + *num2;
                newdata.push(sum)
            }
        }

        Matrix {
            data: newdata, // finally, return addition result using new_data
            row: self.row,
            col: self.col,
        }
    }
}

fn main() {
    let x = Matrix::new(2, 3, &[-6, -5, 0, 1, 2, 3]);
    let y = Matrix::new(2, 3, &[0, 1, 0, 0, 0, 0]);
    // z = x + y;
}

Compiling the program, I got two errors about type mismatch: 编译程序时,我遇到两个有关类型不匹配的错误:

error[E0308]: mismatched types
  --> src/main.rs:36:23
   |
36 |                 sum = *num1 + *num2;
   |                       ^^^^^^^^^^^^^ expected i32, found type parameter
   |
   = note: expected type `i32`
   = note:    found type `T`

error[E0308]: mismatched types
  --> src/main.rs:41:9
   |
41 |         Matrix {
   |         ^ expected type parameter, found i32
   |
   = note: expected type `Matrix<T>`
   = note:    found type `Matrix<i32>`

My thoughts: 我的想法:

  1. num1 would deref the vector and get a integer type, that's why I use a sum to record the result. num1将取消引用向量并获得整数类型,这就是为什么我使用总和来记录结果的原因。
  2. I am trying to return a Matrix type value at the end of the function. 我正在尝试在函数末尾返回Matrix类型值。

What is going wrong? 怎么了?

This is the entire knowledge of your types that the code can rely on inside of the method: 这是代码可以依靠的方法类型的全部知识:

impl<T: ops::Add<Output = T> + Copy> ops::Add for Matrix<T> {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        // ...
    }
}

Based on that, how would it be possible to make this assumption? 基于此,怎么可能做这个假设?

num1 would deref the vector and get a integer type num1将解引用向量并获得整数类型

There is no way to know what concrete type T will be! 没有办法知道具体的T型将是什么!

Beyond that, even if it were some integer type, how would it be possible to assume that summing into an i32 is acceptable? 除此之外,即使它是某种整数类型,又怎么可能假设将一个i32是可以接受的呢? What if T were a i64 ? 如果Ti64怎么i64

The solution is to remove any assumptions and let the compiler do its job. 解决方案是删除所有假设,并让编译器完成工作。 Remove the type annotation from sum and the code compiles. sum删除类型注释,并编译代码。 I find it good practice to always allow the compiler to infer my types when possible. 我发现最好总是允许编译器在可能的情况下推断我的类型。

See also: 也可以看看:

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

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