简体   繁体   English

重载Add-operator而不复制操作数

[英]Overloading the Add-operator without copying the operands

I'm writing an application in Rust that will have to use vector arithmetic intensively and I stumbled upon a problem of designing operator overload for a structure type. 我正在Rust中编写一个应用程序,它必须集中使用向量算法,我偶然发现了为结构类型设计运算符重载的问题。

So I have a vector structure like that: 所以我有一个这样的矢量结构:

struct Vector3d {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

and I want to be able to write something like that: 我希望能够写出类似的东西:

let x = Vector3d {x:  1.0, y: 0.0, z: 0.0};
let y = Vector3d {x: -1.0, y: 0.0, z: 0.0};

let u = x + y;

As far as I can see, there are three different ways to do it: 据我所知,有三种不同的方法:

  1. Implement std::ops::Add trait for Vector3d directly. 实现std::ops::Add直接为Vector3d std::ops::Add特征。 That works, but this trait's method signature is: 这有效,但这个特征的方法签名是:

     fn add(self, other: Vector3d) 

So it will invalidate its arguments after usage (because it moves them) which is undesirable in my case since many vectors will be used in multiple expressions. 所以它会在使用后使它的参数无效(因为它会移动它们),这在我的情况下是不可取的,因为许多矢量将用在多个表达式中。

  1. Implement Add trait for Vector3d and also implement the Copy trait. 实现为Vector3d Add特征并实现Copy特征。 This works, but I feel iffy on that since Vector3d isn't exactly a lightweight thing (24 bytes at least) that can be copied quickly, especially when there are many calls to arithmetic functions. 这是有效的,但我觉得很Vector3d ,因为Vector3d不是一个轻量级的东西(至少24字节),可以快速复制,特别是当有很多调用算术函数时。

  2. Implement Add for references to Vector3d , as suggested here . 实施Add了参考文献Vector3d ,如建议在这里 This works, but in order to apply the operator, I will have to write 这是有效的,但为了应用运算符,我将不得不写

     let u = &x + &y; 

I don't like this notation because it doesn't exactly looks like its mathematic equivalent, just u = x + y . 我不喜欢这种表示法,因为它看起来不像它的数学等价物,只是u = x + y

I'm not sure which variant is optimal. 我不确定哪种变体是最佳的。 So, the question is: is there a way to overload the '+' operator in such a way that 所以,问题是:有没有办法以这样的方式重载'+'运算符

  1. It accepts its arguments as references instead of copying or moving them; 它接受其参数作为引用,而不是复制或移动它们;
  2. It allows to write just u = x + y instead of u = &x + &y ? 它只允许写u = x + y而不是u = &x + &y

Is there a way to overload the '+' operator in such a way that 有没有办法以这种方式重载'+'运算符

  1. It accepts its arguments as references instead of copying or moving them; 它接受其参数作为引用,而不是复制或移动它们;
  2. It allows to write just u = x + y instead of u = &x + &y ? 它只允许写u = x + y而不是u = &x + &y

No , there is no way to do that. ,没有办法做到这一点。 Rust greatly values explicitness and hardly converts between types automatically. Rust非常重视显性,并且几乎不会在类型之间自动转换。

However, the solution to your problem is simple: just #[derive(Copy)] . 但是,问题的解决方案很简单: 只需#[derive(Copy)] I can assure you that 24 bytes are not a lot. 我可以向你保证,24字节不是很多。 Computers these days love to crunch a lot of data at once instead of working on little chunks of data. 如今,计算机喜欢立即处理大量数据而不是处理少量数据。


Apart from that, Copy is not really about the performance overhead of copying/cloning: 除此之外, Copy并不是关于复制/克隆的性能开销:

Types that can be copied by simply copying bits (ie memcpy ). 只需复制位即可复制的类型(即memcpy )。

And later in the documentation : 后来在文档中

Generally speaking, if your type can implement Copy , it should. 一般来说,如果你的类型可以实现Copy ,它应该。

Your type Vector3d can be copied by just copying bits, so it should implement Copy (by just #[derive()] ing it). 您可以通过复制位来复制Vector3d类型,因此它应该实现Copy (仅通过#[derive()]来实现)。

The performance overhead is a different question. 性能开销是一个不同的问题。 If you have a type that can (and thus does) implement Copy , but you still think the type is too big (again: 24 bytes aren't!), you should design all your methods in a way that they accept references (it's not that easy; please read Matthieu's comment). 如果你有一个类型可以(并因此)实现Copy ,但你仍然认为类型太大(再次:24个字节不是!), 你应该以他们接受引用的方式设计你的所有方法 (它是不那么容易;请阅读Matthieu的评论)。 This also includes the Add impl. 这还包括Add impl。 And if you want to pass something to a function by reference, the programmer shall explicitly write it. 如果你想通过引用将某些东西传递给函数,程序员应该明确地写它。 That's what Rust's philosophy would say anyway. 这就是Rust的哲学无论如何都会说的。

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

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