问题
I'm creating a simple matrix struct in Rust and I'm trying to implement some basic operator methods:
use std::ops::Mul;
struct Matrix {
cols: i32,
rows: i32,
data: Vec<f32>,
}
impl Matrix {
fn new(cols: i32, rows: i32, data: Vec<f32>) -> Matrix {
Matrix {
cols: cols,
rows: rows,
data: data,
}
}
}
impl Mul<f32> for Matrix {
type Output = Matrix;
fn mul(&self, m: f32) -> Matrix {
let mut new_data = Vec::with_capacity(self.cols * self.rows);
for i in 0..self.cols * self.rows {
new_data[i] = self.data[i] * m;
}
return Matrix {
cols: *self.cols,
rows: *self.rows,
data: new_data,
};
}
}
fn main() {}
I'm still familiarizing myself with Rust and systems programming and I'm sure the error is pretty obvious. The compiler tells me:
error[E0053]: method `mul` has an incompatible type for trait
--> src/main.rs:22:5
|
22 | fn mul(&self, m: f32) -> Matrix {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Matrix`, found &Matrix
|
= note: expected type `fn(Matrix, f32) -> Matrix`
found type `fn(&Matrix, f32) -> Matrix`
It's referring to the contents of the for loop (I believe). I've tried playing around with a few other things but I can't get my head around it.
回答1:
The error message is spot-on here:
error[E0053]: method `mul` has an incompatible type for trait
--> src/main.rs:22:5
|
22 | fn mul(&self, m: f32) -> Matrix {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Matrix`, found &Matrix
|
= note: expected type `fn(Matrix, f32) -> Matrix`
found type `fn(&Matrix, f32) -> Matrix`
Let's look at the Mul trait to see why your implementation doesn't match:
pub trait Mul<RHS = Self> {
type Output;
fn mul(self, rhs: RHS) -> Self::Output;
}
This says that unless you specify anything further, RHS will be the same type as Self. Self is the type that the trait will be implemented on. Let's look at your definition:
impl Mul<f32> for Matrix {
type Output = Matrix;
fn mul(&self, m: f32) -> Matrix {}
}
In your case, you have substituted f32 for RHS, and Matrix for Output. Also, Matrix is the implementing type. Let's take the trait definition and substitute in, producing some pseudo-Rust:
pub trait Mul {
fn mul(self, rhs: f32) -> Matrix;
}
Now do you see what is different?
// Trait
fn mul(self, m: f32) -> Matrix;
// Your implementation
fn mul(&self, m: f32) -> Matrix;
You have incorrectly specified that you take &self instead of self.
For completeness, here's the implementation. I threw in style fixes at no charge!
impl Mul<f32> for Matrix {
type Output = Matrix;
fn mul(self, m: f32) -> Matrix {
let new_data = self.data.into_iter().map(|v| v * m).collect();
Matrix {
cols: self.cols,
rows: self.rows,
data: new_data,
}
}
}
This is a bit inefficient as it deallocates and reallocates the data vector. Since you are taking the Matrix by value, we can just edit it in place:
impl Mul<f32> for Matrix {
type Output = Matrix;
fn mul(mut self, m: f32) -> Matrix {
for v in &mut self.data {
*v *= m
}
self
}
}
来源:https://stackoverflow.com/questions/33765397/method-mul-has-an-incompatible-type-for-trait