Rust 对于向量类型,高效实现Add特征的首选方法是什么

Rust 对于向量类型,高效实现Add特征的首选方法是什么,rust,Rust,Add特征定义为 当为向量实现它时,需要将其复制到add方法中,以允许类似v1+v2的语法。如果将add实现更改为支持借用引用,从而阻止复制,则必须写入&v1+&v2,这是不可取的 这样做的首选或最佳方式是什么 在C++中,自会是const向量,以及RHS,但仍然允许所需的v1+v2语义。 代码 为了完整起见,我现在使用的代码摘录 use std::num::Float; use std::ops::Add; #[derive(Debug, PartialEq, Eq, Copy)] pub

Add特征定义为

当为向量实现它时,需要将其复制到add方法中,以允许类似v1+v2的语法。如果将add实现更改为支持借用引用,从而阻止复制,则必须写入&v1+&v2,这是不可取的

这样做的首选或最佳方式是什么

<>在C++中,自会是const向量,以及RHS,但仍然允许所需的v1+v2语义。

代码 为了完整起见,我现在使用的代码摘录

use std::num::Float;
use std::ops::Add;

#[derive(Debug, PartialEq, Eq, Copy)]
pub struct Vector<T: Float> {
    x: T,
    y: T,
    z: T,
}

impl<T: Float> Add for Vector<T> {
    type Output = Vector<T>;

    // Probably it will be optimized to not actually copy self and rhs for each call !
    #[inline(always)]
    fn add(self, rhs: Vector<T>) -> Vector<T> {
      Vector {  x: self.x + rhs.x,
                y: self.y + rhs.y, 
                z: self.z + rhs.z }
    }
}


#[cfg(test)]
#[test]
fn basics() {
    let v32 = Vector { x: 5.0f32, y: 4.0f32, z: 0.0f32 };
    let v32_2 = v32 + v32;
    assert_eq!(v32_2.x, v32.x + v32.x);
    assert_eq!(v32_2.y, v32.y + v32.y);
    assert_eq!(v32_2.z, v32.z + v32.z);
}
由于向量只包含三个实现Float-trait的值,这意味着它们要么是f64要么是f32,所以不必担心它们被复制,除非您已经分析了程序并确定多个副本会导致性能下降

例如,如果您的类型不可复制,并且在构造时需要分配大整数和大浮点数,则可以实现所有可能的按值和按引用调用组合:

impl Add<YourType> for YourType { ... }
impl<'r> Add<YourType> for &'r YourType { ... }
impl<'a> Add<&'a YourType> for YourType { ... }
impl<'r, 'a> Add<&'a YourType> for &'r YourType { ... }

在我看来很整洁-编译器已经很好地内联了所有操作。

我个人认为,当使用“拥有”值时,编译器应该能够做得更好,因为它可以随意移动它们。我通常担心会产生不必要的副本,但在这方面,锈蚀可能会有所不同。正如我所想,锈蚀类型包括它们的“修改器”,如mut或&。Add被定义为pub-trait-Add,所以我假设Self的类型在所有方面都必须与RHS的类型相同。也许这也和生命有关。SomeType只定义了一个默认的类型参数,也就是说,如果没有指定它,则假定它是这样的。这允许书写,例如T:Add,翻译成T:Add。谢谢!我现在有很多尤里卡时刻,我试图学习锈迹的来龙去脉!就在几分钟前,我见过这样的代码,并正确地假设它是默认类型。就我而言,由于某些原因,我感到困惑。今天就到此为止,因为情况不再好转;这一答案在本文件中引用。
shrq    $11, %r14
cvtsi2sdq   %r14, %xmm0
mulsd   .LCPI0_0(%rip), %xmm0
shrq    $11, %r15
cvtsi2sdq   %r15, %xmm1
mulsd   .LCPI0_0(%rip), %xmm1
shrq    $11, %rbx
cvtsi2sdq   %rbx, %xmm2
mulsd   .LCPI0_0(%rip), %xmm2
movaps  %xmm0, %xmm3
addsd   %xmm1, %xmm3
movaps  %xmm1, %xmm4
addsd   %xmm2, %xmm4
movaps  %xmm0, %xmm5
addsd   %xmm2, %xmm5
addsd   %xmm2, %xmm3
addsd   %xmm0, %xmm4
addsd   %xmm1, %xmm5
movsd   %xmm3, 24(%rsp)
movsd   %xmm4, 32(%rsp)
movsd   %xmm5, 40(%rsp)
leaq    (%rsp), %rdi
leaq    24(%rsp), %rsi
callq   _ZN13Vec3$LT$T$GT$9to_string20h7039822990634233867E