没有复制生锈的通用数学

por*_*y11 4 generics math rust

我想写一些通用的数学函数,而不假设我的类型是可复制的.这似乎是不可能的,因为数学运算符消耗了这些值,而不是借用它们.所以需要复制对象,只是为了简单的数学运算.我也可以移动它们,但是当我想改变一个结构时,这在借用的上下文中是不可能的.

这里有一些简单的例子,问题在哪里:

use std::ops::Add;

struct NoCopy<T>(T); //some non-copyable struct, (maybe a vector)
struct Cont<T>(NoCopy<T>); //some struct contaioning a noncopyable struct

impl<T: Add<Output=T>> Add for NoCopy<T> {
    type Output = NoCopy<T>;
    fn add(self, x: NoCopy<T>) -> NoCopy<T> {
        NoCopy(self.0+x.0)
    }
}

fn main() {
    let x = NoCopy(1);
    let cont = Cont(x);
    let rel = NoCopy(2);
    cont.0=cont.0+rel; //addition makes struct cont invalid, so i have to copy
}
Run Code Online (Sandbox Code Playgroud)

当我只想用结构的不可复制对象(例如向量的长度)计算某些东西时,它将无法工作,因为该值将被消耗,因此结构变得无效,或借用检查器说"不能摆脱借来的背景".在改变结构时,我如何才能正确使用泛型数学?它是否只适用于可复制类型(或显式克隆)?

Chr*_*son 9

一种选择是Add在参考文献上实施:

impl<'a, T: Copy + Add<Output = T>> Add for &'a NoCopy<T> {
    type Output = NoCopy<T>;
    fn add(self, rhs: Self) -> NoCopy<T> {
        NoCopy(self.0+rhs.0)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是好的,因为共享引用是Copy.注意我添加了一个Copy约束来T使这个实现变得简单(对整数来说是true); 如果T不是复制,那么单线方法可能需要更改.

你必须在使用它时添加引用,这是一种耻辱,但它可以工作:

fn main() {
    let x = NoCopy(1);
    let mut cont = Cont(x);
    let rel = NoCopy(2);
    cont.0=&cont.0+&rel;
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)