我应该在新类型上实现 AddAssign 吗?

Should I implement AddAssign on a newtype?

我有一个新类型:

struct NanoSecond(u64);

我想为此实现加法。 (我实际上使用的是 derive_more,但这是一个 MCVE。)

impl Add for NanoSecond {
    fn add(self, other: Self) -> Self {
        self.0 + other.0
    }
}

但是我应该实施 AddAssign 吗?这是工作所必需的吗?

let mut x: NanoSecond = 0.to();
let y: NanoSecond = 5.to();
x += y;

实施会不会产生意想不到的效果?

+= 运算符确实需要实施 AddAssign

是否实现此特性的决定在很大程度上取决于您所针对的实际类型和语义种类。这适用于您自己制作的任何类型,包括新类型。最重要的先验是可预测性:一个实现应该按照相同数学运算的预期表现。在这种情况下,考虑到通过 Add 的加法已经为该类型定义好, 没有什么能阻止您实现等效操作 in-place,然后添加一个impl of AddAssign 像这样是最可预测的事情。

impl AddAssign for NanoSecond {
    fn add_assign(&mut self, other: Self) {
        self.0 += other.0
    }
}

也可以选择为引用类型提供额外的实现作为第二个操作数(例如 Add<&'a Self>AddAssign<&'a Self>)。

请注意,Clippy 具有检查算术运算的执行是否正确的 lints (suspicious_arithmetic_impl and suspicious_op_assign_impl)。作为可预测性的一部分,无论使用 + 还是 +=,特征的行为都应该与相应的数学运算非常相似。不过,据我所知,目前没有 lint 或 API 指南建议在相应操作的同时实施 -Assign 特征。