rust 为自定义类型实现AddAssign:'二进制赋值运算'+='不能应用于类型'

fhg3lkii  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(93)

我刚接触Rust,想用它重写一些工作中使用的模拟。我正在尝试在Rust中实现我自己版本的超二元数,因为现有的库不太适合我的需要。为此,我创建了一个结构体来保存标量值和标量值的向量:

#[derive(Debug, Clone)]
struct Infinitesimal<F>{
    value : F,
    diffs : Array1<F>
}

更详细地说,Array1来自crate ndarray,并从其结构体ArrayBase<S,D>派生而来。如果我正确阅读了文档,这确实实现了AddAddAssign

impl<'a, A, S, S2, D, E> AddAssign<&'a ArrayBase<S2, E>> for ArrayBase<S, D> {
...
}

我成功地实现了Add特征,没有任何问题

impl<F: Add<Output = F>> Add for Infinitesimal<F> where
    Array1<F> : Add<Output=Array1<F>>{
    
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        Self {
            value: self.value + rhs.value,
            diffs: self.diffs + rhs.diffs,
        }
    }
}

同样,我也可以用同样的方法成功地定义和编译AddAssign trait。

impl<F: AddAssign> AddAssign for Infinitesimal<F> where
    Array1<F> : AddAssign{

    fn add_assign(&mut self, rhs: Self) {
        (*self).value += rhs.value;
        (*self).diffs += rhs.diffs;
    }
}

但是,在运行时,出现了一些问题,我无法在结构体的可变示例上实际使用+=操作符。当我尝试执行这个简单操作时,遇到了一个错误。

let mut x:Infinitesimal<f64>= Infinitesimal::new(1.0);
    x+=Infinitesimal::new(1.0);

::new(a)只会将value设置为a,并将diffs设置为已清零的数组)

error[E0368]: binary assignment operation `+=` cannot be applied to type `Infinitesimal<f64>`
 --> src/main.rs:8:5
  |
8 |     x+=y;
  |     -^^^
  |     |
  |     cannot use `+=` on type `Infinitesimal<f64>`

我试过把trait写得更像in the docs,但无济于事。我也试过这种混乱的编译,但不仅是多余的,而且给了我同样的[E0368]错误。

impl<F> AddAssign<Infinitesimal<F>> for Infinitesimal<F> where
    F:          AddAssign<F>,
    Array1<F> : AddAssign<Array1<F>>{

    fn add_assign(&mut self, rhs: Self) {
        (*self).value += rhs.value;
        (*self).diffs += rhs.diffs;
    }
}

这可能是一个简单的问题。在这一点上,我认为最好询问更有经验的开发人员是否有任何明显的问题,我还不能看到。我可以得到一些帮助吗?

n53p2ov0

n53p2ov01#

感谢@cafce25的提问,因为它帮助我更仔细地查看文档。为Array1定义的AddAssign为RHS提供了一个引用:

impl<'a, A, S, S2, D, E> AddAssign<&'a ArrayBase<S2, E>> for ArrayBase<S, D> {
...
}

我已经修改了我自己的实现来匹配,在需要的地方添加了适当的生命周期。它现在工作得很好!

impl<'a, F> AddAssign<&'a Infinitesimal<F>> for Infinitesimal<F> where
    F:          AddAssign<&'a F>,
    Array1<F> : AddAssign<&'a Array1<F>>{

    fn add_assign(&mut self, rhs: &'a Self) {
        (*self).value += &rhs.value;
        (*self).diffs += &rhs.diffs;
    }
}

相关问题