如何为自定义结构体类型实现Mul Trait以实现双向工作

3
// main.rs
#[derive(Clone, Copy)]
struct A(f64, f64);
impl<T> Mul<T> for A
where
    f64: From<T>,
    T: Copy, // f64: Mul<T>,
{
    type Output = A;
    fn mul(mut self, rhs: T) -> Self::Output {
        self.0 = self.0 * f64::from(rhs);
        self.1 = self.1 * f64::from(rhs);
        self
    }
}

impl Mul<A> for i32 {
    type Output = A;
    fn mul(self, mut rhs: A) -> Self::Output {
        rhs.0 = rhs.0 * f64::from(self);
        rhs.1 = rhs.1 * f64::from(self);
        rhs
    }
}

fn main() {
    let mut a = A(1.0, 1.0);
    a = a * 2;             // is fine
    a = a * 2.0;           // is fine
    a = a * 1 as u8;       // is fine

    a = 2 * a;             // is fine because I did implement for i32 type
    a = 2.0 * a;           // impl this with generic type!
}

我能够为我的结构体 A 实现具有泛型参数 TMul 特质。
impl<T> Mul<T> for A
where
    f64: From<T>,
    T: Copy, 
{
    type Output = A;
    fn mul(mut self, rhs: T) -> Self::Output {
        self.0 = self.0 * f64::from(rhs);
        self.1 = self.1 * f64::from(rhs);
        self
    }
}

现在我可以将A与任何数字类型相乘,如A * f64A * i32等。
但我无法使用泛型参数实现Mul Trait,这使我需要这样做:f64 * Ai32 * A
是否有任何方法可以像这样实现它?
impl Mul<A> for i32 {
    type Output = A;
    fn mul(self, mut rhs: A) -> Self::Output {
        rhs.0 = rhs.0 * f64::from(self);
        rhs.1 = rhs.1 * f64::from(self);
        rhs
    }
}

但对于所有类型 (泛型参数)

impl<T> Mul<A> for T { // error:type parameter `T` must be covered by another type when it appears before the first local type
    type Output = A;
    fn mul(self, mut rhs: A) -> Self::Output {
        rhs.0 = rhs.0 * f64::from(self);
        rhs.1 = rhs.1 * f64::from(self);
        rhs
    }
}

完整错误:

error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`A`)
  --> src\main.rs:64:6
   |
64 | impl<T> Mul<A> for T {
   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`A`)
   |
   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last

For more information about this error, try `rustc --explain E0210`.
1个回答

5
你无法这样做。你只能为右侧参数使用泛型。
通常,库解决此问题的方法是对于Self * T进行泛型实现,然后制作一个宏,通过显式将T替换为他们支持的类型列表来实现T * Self,例如nalgebra中所示:
left_scalar_mul_impl!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);

关于为什么不可能的讨论,请参见:https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html - cadolphs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接