我正在编写光线追踪器,并且希望能够减去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;
}
我收到编译器的投诉:
error[E0382]: use of moved value: `x`
--> src/main.rs:26:13
|
25 | let a = x - y;
| - value moved here
26 | let b = x - y;
| ^ value used here after move
|
= note: move occurs because `x` has type `Vec3`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `y`
--> src/main.rs:26:17
|
25 | let a = x - y;
| - value moved here
26 | let b = x - y;
| ^ value used here after move
|
= note: move occurs because `y` has type `Vec3`, which does not implement the `Copy` trait
如何编写减法运算符,以便上面的代码起作用?
请不要告诉我我应该使用现有的3D数学模块。我敢肯定还有更好的方法,但是我是在自己学习如何学习语言之后。
How do I implement the Add trait for a reference to a struct?无济于事,因为它需要为尚不存在的对象指定生存期。
答案 0 :(得分:4)
在该示例中,编译器告诉您x
为何因移动而无效:
= note: move occurs because `x` has type `Vec3`, which does not implement the `Copy` trait
在这种情况下,您只需添加#[derive(Copy)]
即可获得Vec3
复制语义 :
#[derive(Clone, Copy, Debug)]
pub struct Vec3 {
pub v: [f64; 3],
}
Copy
是一个标记特征,它向编译器指示类型的值在移出时不会变为无效。具有此属性的类型被称为具有复制语义,而未实现Copy
的类型被称为具有移动语义。 Is it possible to make a type only movable and not copyable?和How does Rust provide move semantics?更详细地解释了这个概念。
但是,您只能为仅包含其他Copy
类型的类型实现Copy
。如果Vec3
实际上在其中包含Vec
,则编译器将不允许您为其实现Copy
。幸运的是,引用确实实现了Copy
,因此您可以使用How do I implement the Add trait for a reference to a struct?
Sub
的引用的Vec3
。 >