【问题标题】:Generic Type Mismatch using Trait in Rust在 Rust 中使用 Trait 的泛型类型不匹配
【发布时间】:2016-11-04 00:57:52
【问题描述】:

我正在使用特征进行矩阵加法。我被泛型类型不匹配所困扰。我的代码如下:

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 会取消引用向量并获得整数类型,这就是我使用 sum 来记录结果的原因。
  2. 我试图在函数末尾返回一个Matrix 类型值。

出了什么问题?

【问题讨论】:

    标签: rust traits


    【解决方案1】:

    这是代码可以在方法内部依赖的类型的全部知识:

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

    基于此,怎么可能做出这样的假设?

    num1 将取消引用向量并获得整数类型

    没有办法知道T 会是什么具体类型!

    除此之外,即使它是 some 整数类型,又怎么可能假设对 i32 求和是可以接受的呢?如果Ti64 会怎样?

    解决方案是消除任何假设,让编译器完成其工作。从sum 中删除类型注释并且代码编译。我发现总是允许编译器在可能的情况下推断我的类型是一种很好的做法。

    另见:

    【讨论】:

      猜你喜欢
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      • 2010-09-20
      • 1970-01-01
      相关资源
      最近更新 更多