1

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.
  2. I am trying to return a Matrix type value at the end of the function.

What is going wrong?

0

1 Answer 1

6

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

There is no way to know what concrete type T will be!

Beyond that, even if it were some integer type, how would it be possible to assume that summing into an i32 is acceptable? What if T were a 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. I find it good practice to always allow the compiler to infer my types when possible.

See also:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.