Generics 使用泛型进行算术运算时,无法应用二进制运算

Generics 使用泛型进行算术运算时,无法应用二进制运算,generics,rust,Generics,Rust,我试图在我的库中使用实现泛型,但我一直在与编译器斗争。这项工作: struct Vector<T> { data: Vec<T>, } trait Metric<T> { fn norm(&self) -> T; } impl Metric<f32> for Vector<f32> { fn norm(&self) -> f32 { let mut s = 0.0;

我试图在我的库中使用实现泛型,但我一直在与编译器斗争。这项工作:

struct Vector<T> {
    data: Vec<T>,
}

trait Metric<T> {
    fn norm(&self) -> T;
}

impl Metric<f32> for Vector<f32> {
    fn norm(&self) -> f32 {
        let mut s = 0.0;

        for u in &self.data {
            s = s + u * u;
        }

        s.sqrt()
    }
}
如果我删除引用并迭代
self.data
,我会得到一个

错误[E0507]:无法移出借用的内容
-->src/lib.rs:15:18
|
15 |对于自我数据中的u{
|^^^^^^^^^^^无法移出借用的内容
让我们更仔细地看一下这个特征。它的定义是:

pub trait Float: NumCast + Num + Copy + Neg<Output = Self> + PartialOrd<Self> {
    // ...
}
深入

这会产生相同的错误:
二进制操作“*`不能应用于类型“&T”

问题是,只有知道可以将一个
T
乘以另一个
T
。也就是说,必须显式地取消对变量的引用。因为
Float
也需要
Copy
,这将起作用:

let z = (*a) * (*b);
对原始代码应用相同的更改会使其正常工作:

for u in &self.data {
    s = s + (*u) * (*u);
}
模式匹配时,还可以取消对迭代器变量的引用:

for &u in &self.data {
    s = s + u * u;
}
或者,您可以添加另一个绑定,该绑定要求对您的类型的引用可以相乘:

impl<T> Metric<T> for Vector<T>
where
    T: Float,
    for<'a> &'a T: std::ops::Mul<&'a T, Output = T>,
{
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + u * u;
        }

        s.sqrt()
    }
}
另见:


谢谢你澄清这一点-了解为什么会出现这种情况真的很有帮助。至于+=部分,我是否正确地假设不可能将此运算符用于泛型?@user124784,但它即将到来。因为该运算符比你预期的更难:-)我可以等待:)。只是检查一下-编译器的优化不会失败这些有什么区别吗?
let z = (*a) * (*b);
for u in &self.data {
    s = s + (*u) * (*u);
}
for &u in &self.data {
    s = s + u * u;
}
impl<T> Metric<T> for Vector<T>
where
    T: Float,
    for<'a> &'a T: std::ops::Mul<&'a T, Output = T>,
{
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s = s + u * u;
        }

        s.sqrt()
    }
}
impl<T> Metric<T> for Vector<T>
where
    T: Float + std::ops::AddAssign,
    for<'a> &'a T: std::ops::Mul<&'a T, Output = T>,
{
    fn norm(&self) -> T {
        let mut s = T::zero();

        for u in &self.data {
            s += u * u;
        }

        s.sqrt()
    }
}