英文:
expected struct `Vec3d`, found type parameter `u32` when implmenting the Mul trait for a custom struct
问题
我正在尝试为 Vec3d
结构实现 Mul
特性。我想要 mul
函数将 Vec3d
的每个元素与一个数字相乘并返回一个 Vec3d
。但是我遇到了以下错误:
error[E0053]: method `mul` has an incompatible type for trait
--> src\vec_3d.rs:26:21
|
23 | impl<u32> Mul for Vec3d<u32> {
| --- this type parameter
...
26 | fn mul(self, t: u32) -> Self::Output {
| ^^^
| |
| expected struct `Vec3d`, found type parameter `u32`
| help: change the parameter type to match the trait: `Vec3d<u32>`
|
= note: expected fn pointer `fn(Vec3d<_>, Vec3d<u32>) -> Vec3d<_>`
found fn pointer `fn(Vec3d<_>, u32) -> Vec3d<_>`
我的代码如下:
use std::ops::Add;
use std::ops::Mul;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Vec3d<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<u32> Mul for Vec3d<u32> {
type Output = Self;
fn mul(self, t: u32) -> Self::Output {
Self {
x: self.x * t,
y: self.x * t,
z: self.x * t,
}
}
}
我最初是这样写的,使用通用类型参数 T
:
impl<T: Mul<Output = T>> Mul for Vec3d<T> {
type Output = Self;
fn mul(self, t: T) -> Self::Output {
Self {
x: self.x * t,
y: self.x * t,
z: self.x * t,
}
}
}
我在一些示例和其他问题中看到过这样的写法。有什么问题,以及如何正确实现它呢?
英文:
I am trying to implement the Mul
trait for the Vec3d
struct. I want the mul
function to multiply each element of Vec3d
by a number and return a Vec3d
. However I am getting faced with this error:
error[E0053]: method `mul` has an incompatible type for trait
--> src\vec_3d.rs:26:21
|
23 | impl<u32> Mul for Vec3d<u32> {
| --- this type parameter
...
26 | fn mul(self, t: u32) -> Self::Output {
| ^^^
| |
| expected struct `Vec3d`, found type parameter `u32`
| help: change the parameter type to match the trait: `Vec3d<u32>`
|
= note: expected fn pointer `fn(Vec3d<_>, Vec3d<u32>) -> Vec3d<_>`
found fn pointer `fn(Vec3d<_>, u32) -> Vec3d<_>`
My code looks like this:
use std::ops::Add;
use std::ops::Mul;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Vec3d<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<u32> Mul for Vec3d<u32> {
type Output = Self;
fn mul(self, t: u32) -> Self::Output {
Self {
x: self.x * t,
y: self.x * t,
z: self.x * t,
}
}
}
I had this originally with the generic type parameter T
:
impl<T: Mul<Output = T>> Mul for Vec3d<T> {
type Output = Self;
fn mul(self, t: T) -> Self::Output {
Self {
x: self.x * t,
y: self.x * t,
z: self.x * t,
}
}
}
I have seen this be done the same way in some examples and other questions. What is wrong and how I can implement this the correct way?
答案1
得分: 1
这几段代码主要是关于Rust中的乘法操作符(Mul
)的示例和说明,以下是已翻译的部分:
- "This is nearly the same as the example on the
Mul
documentation: Multiplying vectors by scalars as in linear algebra" - "
Mul
has a default generic, which you can see in the trait definition:" - "This offers convenience since most implementers of
Mul
will be multiplying againstSelf
. You aren't, so you need to specify the generic:" - "To make this fully generic, you might try this:"
- "However, since you're using a single
T
3 times, you would need to restrict it toClone
orCopy. The usual way to get around this is to implement
Mul` for references:" - "Then you probably want a non-reference version for when the type implements
Copy
:" - "But even better, you can do both of those in one impl:"
- "When
R
is&T
you cover the first impl, and whenR
isT
andCopy
you cover the second impl.&
references are alwaysCopy
." - "Another common thing to do is implement
Mul
for every integer type, which allows you more control over the implementation, for example if you wanted to optimize them for certain sized integers."
请注意,这些是代码和代码注释的翻译,没有额外的信息。
英文:
This is nearly the same as the example on the Mul
documentation: Multiplying vectors by scalars as in linear algebra
Mul
has a default generic, which you can see in the trait definition:
pub trait Mul<Rhs = Self> {
This offers convenience since most implementers of Mul
will be multiplying against Self
. You aren't, so you need to specify the generic:
impl Mul<u32> for Vec3d<u32> {
type Output = Self;
fn mul(self, t: u32) -> Self::Output {
Self {
x: self.x * t,
y: self.y * t,
z: self.z * t,
}
}
}
To make this fully generic, you might try this:
impl<T: Mul<Output = T>> Mul<T> for Vec3d<T>
However, since you're using a single T
3 times, you would need to restrict it to Clone
or Copy
. The usual way to get around this is to implement Mul
for references:
impl<'a, T> Mul<&'a T> for Vec3d<T>
where
T: Mul<&'a T, Output = T>,
{
type Output = Self;
fn mul(self, t: &'a T) -> Self::Output {
Self {
x: self.x * t,
y: self.y * t,
z: self.z * t,
}
}
}
Then you probably want a non-reference version for when the type implements Copy
:
impl<T> Mul<T> for Vec3d<T>
where
T: Mul<Output = T> + Copy,
{
type Output = Self;
fn mul(self, t: T) -> Self::Output {
Self {
x: self.x * t,
y: self.y * t,
z: self.z * t,
}
}
}
But even better, you can do both of those in one impl:
impl<T, R> Mul<R> for Vec3d<T>
where
R: Copy,
T: Mul<R, Output = T>,
{
type Output = Self;
fn mul(self, t: R) -> Self::Output {
Self {
x: self.x * t,
y: self.y * t,
z: self.z * t,
}
}
}
When R
is &T
you cover the first impl, and when R
is T
and Copy
you cover the second impl. &
references are always Copy
.
Another common thing to do is implement Mul
for every integer type, which allows you more control over the implementation, for example if you wanted to optimize them for certain sized integers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论