簡體   English   中英

實現特征時類型不匹配

[英]Mismatched types when implementing a trait

要學習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實現了Add特性,但是在我嘗試執行此操作的任何地方,我都會得到相同的錯誤或解析錯誤。

我對Matrix的定義是

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

使用T: Add表示您可以寫T + T ,但它不會對由此產生的類型施加任何限制,特別是可能不是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 / the +運算符獲取其參數的所有權,並且無​​法通過直接索引將所有權移出向量(通常,編譯器無法告訴您以后不會再次嘗試訪問移出的索引,這將是一個安全問題)。 幸運的是,有一個解決方案:向量支持移出迭代器,並且可以遍歷self_rhs以鎖定步驟移出:

for (a, b) in self.data.into_iter().zip(_rhs.data.into_iter()) {
    res.data.push(a + b)
}

ab變量均為T類型,即所有權已轉移。


小貼士,實際上可以使代碼“迭代”更多:

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 data = self.data.into_iter()
         .zip(_rhs.data.into_iter())
        .map(|(a,b)| a + b)
        .collect();
    Matrix {
        rows: self.rows,
        cols: self.cols,
        data: data
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM