2016-11-04 8 views
1

Я делаю добавление матрицы, используя черты. Я застрял в несоответствии родового типа. Мой код выглядит следующим образом:Общее несоответствие типа с использованием признака в ржавчине

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

Компиляция программы, я получил два сообщения об ошибках, типа несоответствия:

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

Мои мысли:

  1. num1 бы deref вектор и получить целое число типа, поэтому я использую сумму для записи результата.
  2. Я пытаюсь вернуть значение типа Matrix в конце функции.

Что происходит не так?

ответ

5

Это все знание ваших типов, что код может опираться на внутренней части метода:

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

Основываясь на том, что, как бы это было возможно сделать это предположение?

num1 бы deref вектор и получить целочисленный тип

Там нет никакого способа знать, что конкретный тип T будет!

Кроме того, даже если бы это было целочисленный тип, как можно было бы предположить, что суммирование в i32 приемлемо? Что делать, если T были i64?

Решение состоит в том, чтобы удалить любые предположения и позволить компилятору выполнять свою работу. Удалите аннотацию типа от sum и код компилируется. Я считаю хорошей практикой всегда позволяет компилятору вывести мои типы, когда это возможно.

Смотрите также: