如何为非Copy类型实现Add trait,使调用无需引用?
为非Copy类型的结构体实现算术操作的问题
我正在尝试为结构体D<T>实现算术操作重载:
struct D<T> { reg: f64, deriv: T, }
当T: Copy(比如f64)时,直接实现Add trait就能正常工作,但我希望T也能支持非Copy类型(比如递归定义的枚举)。
我尝试为D<T>和&D<T>的所有组合实现Add trait:
impl<T> Add for D<T> where T: Clone + Add<T, Output = T>, { type Output = D<T>; fn add(self, D { reg, deriv }: Self) -> Self::Output { D { reg: self.reg + reg, deriv: self.deriv + deriv, } } } impl<T> Add for &D<T> where T: Clone + Add<T, Output = T>, { type Output = D<T>; fn add(self, D { reg, deriv }: Self) -> Self::Output { D { reg: self.reg + reg, deriv: self.deriv.clone() + deriv.clone(), } } } impl<T> Add<D<T>> for &D<T> where T: Clone + Add<T, Output = T>, { type Output = D<T>; fn add(self, D { reg, deriv }: D<T>) -> Self::Output { D { reg: self.reg + reg, deriv: self.deriv.clone() + deriv, } } } impl<T> Add<&D<T>> for D<T> where T: Clone + Add<T, Output = T>, { type Output = D<T>; fn add(self, D { reg, deriv }: &D<T>) -> Self::Output { D { reg: self.reg + reg, deriv: self.deriv + deriv.clone(), } } }
但复用同一个D<T>实例时会触发借用检查器错误:
fn f<T>(x: &D<T>) -> D<T> where T: Clone + Add<T, Output = T>, { let y = x + x; y + x + y + x }
错误信息:
use of moved value:
y
value used here after move
我理解这是因为第一个+操作移动了y,可以通过借用y来解决:
fn f<T>(x: &D<T>) -> D<T> where T: Clone + Add<T, Output = T>, { let y = x + x; &y + x + y + x }
我曾尝试把Add的输出类型设为引用,但遇到了生命周期不稳定的问题,而且我希望调用者能拥有结果的所有权,而不是拿到引用。
这一切操作显得很繁琐,我是不是漏掉了某种设计模式?还是说在Rust里手动添加引用是开发者的常规操作?
内容的提问来源于stack exchange,提问作者Kurt Schelfthout
相关产品推荐
相关产品推荐

