You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为非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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 05:49:11