涉及复数和浮点值的运算符重载
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 中,可以通过从 T
到 Complex<T>
的隐式转换来解决这个问题。 Rust 中有类似的技巧吗?有没有更好的方法来定义高效、通用的 *
操作?谢谢。
这应该是允许的,但是有一个 outstanding issue 可以防止在左侧使用内置类型(u8
、f32
等)自定义实现运行时的操作。
目前建议的解决方法是将自定义类型放在左侧,将内置类型放在右侧。
更新:此错误已由 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 中,可以通过从 T
到 Complex<T>
的隐式转换来解决这个问题。 Rust 中有类似的技巧吗?有没有更好的方法来定义高效、通用的 *
操作?谢谢。
这应该是允许的,但是有一个 outstanding issue 可以防止在左侧使用内置类型(u8
、f32
等)自定义实现运行时的操作。
目前建议的解决方法是将自定义类型放在左侧,将内置类型放在右侧。