要学习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>,
}
答案 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