实现特征时类型不匹配

时间:2015-04-29 11:48:29

标签: rust

要学习Rust,我正在构建自己的Matrix类。我对Add trait的实现如下:

impl<T: Add> Add for Matrix<T>
{
    type Output = Matrix<T>;

    fn add(self, _rhs: Matrix<T>) -> Matrix<T>
    {
        assert!(self.rows == _rhs.rows && self.cols == _rhs.cols,
                "attempting to add matrices of different sizes");

        let mut res: Matrix<T> = Matrix::<T>{
            rows: self.rows,
            cols: self.cols,
            data : Vec::<T>::with_capacity(self.rows * self.cols),
        };

        for i in 0..self.rows*self.cols{
            res.data.push(self.data[i] + _rhs.data[i]);
        }
        res
   }
}

但是我收到以下错误

       Compiling matrix v0.1.0 (file://~/soft/rust/projects/matrix)
src/lib.rs:35:27: 35:54 error: mismatched types:
 expected `T`,
    found `<T as core::ops::Add>::Output`
(expected type parameter,
    found associated type) [E0308]
src/lib.rs:35             res.data.push(self.data[i] + _rhs.data[i]);
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~

通过错误报告,我想我需要在其他地方指出T实现了添加特征,但是在我尝试这样做的任何地方我都会得到相同的错误或解析错误。

顺便提一下我对Matrix的定义是

pub struct Matrix<T> {
    pub rows: usize,
    pub cols: usize,
    pub data: Vec<T>,
}

1 个答案:

答案 0 :(得分:4)

使用T: Add作为绑定表示可以编写T + T,但它不会对由此产生的类型施加任何限制,特别是它可能不是{ {1}}。您依靠T才能返回T

一种方法是要求Matrix<T>,以便T: Add<Output = T>返回T + T

T

另一种方法是使用impl<T: Add<Output = T>> Add for Matrix<T> { ... } 想要给出的任何输出:即你的添加将返回T

Matrix<T::Output>

然而,这两个都遇到了问题:

impl<T: Add> Add for Matrix<T>
{
    type Output = Matrix<T::Output>;

    fn add(self, _rhs: Matrix<T>) -> Matrix<T::Output>
    {
        assert!(self.rows == _rhs.rows && self.cols == _rhs.cols,
                "attempting to add matrices of different sizes");

        let mut res = Matrix {
            rows: self.rows,
            cols: self.cols,
            data : Vec::with_capacity(self.rows * self.cols),
        };

        for i in 0..self.rows*self.cols{
            res.data.push(self.data[i] + _rhs.data[i]);
        }
        res
   }
}

<anon>:23:27: 23:39 error: cannot move out of indexed content <anon>:23 res.data.push(self.data[i] + _rhs.data[i]); ^~~~~~~~~~~~ <anon>:23:42: 23:54 error: cannot move out of indexed content <anon>:23 res.data.push(self.data[i] + _rhs.data[i]); ^~~~~~~~~~~~ / Add运算符获取其参数的所有权,并且不能将所有权移出带有直接索引的向量(通常,编译器不能告诉那个赢了&# 39; t尝试再次访问移出的索引,这将是一个安全问题)。幸运的是,有一个解决方案:向量支持一个移出的迭代器,一个人可以走过+self以锁定步骤向外移动:

_rhs

for (a, b) in self.data.into_iter().zip(_rhs.data.into_iter()) { res.data.push(a + b) } a变量都属于b类型,即所有权已移动。

小调,实际上可以&#34; iteratorise&#34;代码甚至更多,写作:

T