简体   繁体   English

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

[英]How do I implement one of the std::ops:{Add, Sub, Mul, Div} operators without moving out the the arguments?

I'm writing a ray-tracer and I want to be able to subtract my 3D vectors: 我正在编写光线追踪器,并且希望能够减去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],
            ],
        }
    }
}

This seems to work. 这似乎有效。 However, when I try to use it: 但是,当我尝试使用它时:

fn main() {
    let x = Vec3 { v: [0., 0., 0.] };
    let y = Vec3 { v: [0., 0., 0.] };
    let a = x - y;
    let b = x - y;
}

I get complaints from the compiler: 我收到编译器的投诉:

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

How can I write the subtraction operator so that the code above works? 如何编写减法运算符,以便上面的代码起作用?

Please don't tell me I should an existing 3D math module. 请不要告诉我我应该使用现有的3D数学模块。 I'm sure there's something better, but I'm after learning how to do it myself to learn the language. 我敢肯定有更好的东西,但是我正在学习如何自己学习语言。

How do I implement the Add trait for a reference to a struct? 如何实现“添加”特征来引用结构? doesn't help as it requires specifying lifetimes for object which I'm not at yet. 这没有帮助,因为它需要为我还没有指定的对象指定生存期。

In the example, the compiler tells you why x has been invalidated by the move: 在该示例中,编译器告诉您x为何由于移动而无效:

   = note: move occurs because `x` has type `Vec3`, which does not implement the `Copy` trait

In this case, you can simply add #[derive(Copy)] to give Vec3 copy semantics : 在这种情况下,您只需添加#[derive(Copy)]即可提供Vec3 复制语义

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

Copy is a marker trait that indicates to the compiler that values of a type do not become invalid when they are moved from. Copy是一个标记特征,它向编译器指示类型的值在移出时不会变为无效。 A type with this property is said to have copy semantics, while a type that does not implement Copy is said to have move semantics. 具有此属性的类型被称为具有复制语义,而未实现Copy的类型被称为具有移动语义。 Is it possible to make a type only movable and not copyable? 是否可以使一种类型只能移动而不能复制? and How does Rust provide move semantics? 以及Rust如何提供移动语义? explain this concept in more detail. 详细解释这个概念。


However, you can only implement Copy for types that contain only other Copy types. 但是,您只能为仅包含其他Copy类型的类型实施Copy If Vec3 actually held a Vec inside it, the compiler would not let you implement Copy for it. 如果Vec3实际上在其中包含Vec ,则编译器将不允许您为其实现Copy Fortunately, references do implement Copy , so you can instead implement Sub for a reference to Vec3 , using the approach described in How do I implement the Add trait for a reference to a struct? 幸运的是,参考文献并实现Copy ,这样你就可以实现,而不是Sub于一个参考 Vec3 ,使用描述的方法如何落实到一个结构的引用添加特质?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM