gpt4 book ai didi

rust - 实现特征时类型不匹配

转载 作者:行者123 更新时间:2023-11-29 08:12:51 28 4
gpt4 key购买 nike

为了学习 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/+运算符获得其参数的所有权,并且不能将所有权从具有直接索引的向量中移出(通常,编译器无法告诉您以后不会再次尝试访问移出的索引,这将是安全问题)。幸运的是,有一个解决方案:向量支持移出迭代器,并且可以遍历 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
}
}

关于rust - 实现特征时类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29942840/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com