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

时间:2018-08-14 15:17:49

标签: 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: [
                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?无济于事,因为它需要为尚不存在的对象指定生存期。

1 个答案:

答案 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。 >
相关问题
最新问题