Rust 如何实现std::ops:{Add,Sub,Mul,Div}操作符之一而不移出参数?

Rust 如何实现std::ops:{Add,Sub,Mul,Div}操作符之一而不移出参数?,rust,Rust,我正在写一个光线跟踪器,我希望能够减去我的3D向量: use std::ops::Sub; #[derive(Clone, Debug)] pub struct Vec3 { pub v: [f64; 3], } impl Sub for Vec3 { type Output = Vec3; fn sub(self, other: Vec3) -> Vec3 { Vec3 { v: [ s

我正在写一个光线跟踪器,我希望能够减去我的3D向量:

use std::ops::Sub;

#[derive(Clone, Debug)]
pub struct Vec3 {
    pub v: [f64; 3],
}

impl Sub for Vec3 {
    type Output = Vec3;

    fn sub(self, other: Vec3) -> Vec3 {
        Vec3 {
            v: [
                self.v[0] - other.v[0],
                self.v[1] - other.v[1],
                self.v[2] - other.v[2],
            ],
        }
    }
}
这似乎奏效了。但是,当我尝试使用它时:

fn main() {
    let x = Vec3 { v: [0., 0., 0.] };
    let y = Vec3 { v: [0., 0., 0.] };
    let a = x - y;
    let b = x - y;
}
我收到编译器的投诉:

错误[E0382]:使用移动值:`x`
-->src/main.rs:26:13
|
25 |设a=x-y;
|-价值转移到这里
26 |设b=x-y;
|^移动后此处使用的值
|
=注意:发生移动是因为'x'具有'Vec3'类型,该类型未实现'Copy'特性
错误[E0382]:使用移动的值:`y`
-->src/main.rs:26:17
|
25 |设a=x-y;
|-价值转移到这里
26 |设b=x-y;
|^移动后此处使用的值
|
=注意:发生移动是因为'y'具有'Vec3'类型,该类型未实现'Copy'特性
如何编写减法运算符以使上述代码正常工作

请不要告诉我应该使用现有的3D数学模块。我相信还有更好的方法,但我已经学会了如何自己去学习这门语言


没有帮助,因为它需要为我还不知道的对象指定生命周期

在本例中,编译器会告诉您为什么移动导致
x
无效:

=注意:发生移动是因为'x'具有'Vec3'类型,该类型不实现'Copy'特性
在这种情况下,您只需添加
#[派生(复制)]
即可给出
Vec3
复制语义:

Copy
是一种标记特征,它向编译器指示类型的值在从中移动时不会变得无效。具有此属性的类型称为具有复制语义,而未实现
copy
的类型称为具有移动语义。并更详细地解释这个概念



但是,您只能对仅包含其他
Copy
类型的类型实现
Copy
。如果
Vec3
实际上在其中包含
Vec
,编译器将不允许您为其实现
Copy
。幸运的是,引用确实实现了
Copy
,因此您可以使用中描述的@trentcl可能重复的方法,为
Vec3
的引用实现
Sub
,谢谢!!考虑一下这个问题。我还在处理其他的选择,但因为我还不知道什么是生命,我很难比较它们。您的建议解决了我的问题,但我不确定副本是否是正确的权衡。@Jeffrey the
copy
标记允许在需要时默默地复制您的结构。我不认为最后一段是对问题的合理约束。你会问你的驾驶老师“我如何平行停车?哦,但我不能转动方向盘,因为我还没有转向。”幸运的是,在这种情况下,不需要使用寿命(请看我的答案),并且链接的问题无论如何也不能解决提出的问题(你必须使用
&x-&y
而不是
x-y
)。
#[derive(Clone, Copy, Debug)]
pub struct Vec3 {
    pub v: [f64; 3],
}