涉及复数和浮点值的运算符重载

Operator overloading involving complex and float values

更新:此错误已由 https://github.com/rust-lang/rust/pull/23673 修复。下面的代码现在可以使用了。


在数学和数值编程中,人们期望复数与实数(浮点)值无缝互操作。是否可以在 Rust 中定义一个 struct Complex<T: Float> 允许涉及 T 类型值的对称数学运算?

例如,可以为输入 (Complex<T>, Complex<T>)(Complex<T>, T) 定义运算符 *,如下所示:

use std::ops::Mul;
use std::num::Float;

#[derive(Copy, Debug)]
pub struct Complex<T: Float> {
    pub re: T, pub im: T
}

impl<T: Float> Complex<T> {
    pub fn new(re: T, im: T) -> Complex<T> {
        Complex { re: re, im: im }
    }
}

impl<T: Float> Mul<Complex<T>> for Complex<T> {
    type Output = Complex<T>;

    fn mul(self, other: Complex<T>) -> Complex<T> {
        Complex::new(self.re * other.re - self.im * other.im,
                     self.re * other.im + self.im * other.re)
    }
}

impl<T: Float> Mul<T> for Complex<T> {
    type Output = Complex<T>;

    fn mul(self, other: T) -> Complex<T> {
        Complex::new(self.re * other, self.im * other)
    }
}

是否可以重载 * 以同时处理输入 (T, Complex<T>)?例如,以下 工作:

impl Mul<Complex<f64>> for f64 {
    type Output = Complex<f64>;
    fn mul(self, other: Complex<f64>) -> Complex<f64> {
        Complex::new(self * other.re, self * other.im)
    }
}

fn main() {
    let x = Complex::new(1.0, 1.0);
    let y = x*x;
    let z = x*4.0;
    let w = 4.0*x;
}

我收到错误消息:

 error: mismatched types:
 expected `_`,
    found `Complex<_>`
(expected floating-point variable,
    found struct `Complex`) [E0308]
src/main.rs:61     let w = 4.0*x;
                           ^

在 Scala 中,可以通过从 TComplex<T> 的隐式转换来解决这个问题。 Rust 中有类似的技巧吗?有没有更好的方法来定义高效、通用的 * 操作?谢谢。

这应该是允许的,但是有一个 outstanding issue 可以防止在左侧使用内置类型(u8f32 等)自定义实现运行时的操作。

目前建议的解决方法是将自定义类型放在左侧,将内置类型放在右侧。