如何统一采用f64和Complex <f64>的功能?

时间:2019-07-14 21:40:37

标签: types rust

我有两个功能:

fn f1(k1: f64, k2: f64, k3: f64) -> (f64, f64) {
    let a = k1 + k2;
    let b = k2 * k3.sqrt();
    (a + b, a - b)
}
type Z64 = num::complex::Complex<f64>;

fn f2(k1: Z64, k2: Z64, k3: Z64) -> (Z64, Z64) {
    let a = k1 + k2;
    let b = k2 * k3.sqrt();
    (a + b, a - b)
}

代码是相同的,只是类型不同。一个是f64。另一个是Complex<f64>。两种类型都可能有一个单一的功能多态性吗?

1 个答案:

答案 0 :(得分:3)

由于std中没有sqrt的特征,并且Complex没有实现num_traits::Float,因此您必须为此制定自己的特征。

trait Sqrt {
    fn sqrt(self) -> Self;
}

impl Sqrt for f64 {
    fn sqrt(self) -> Self {
        f64::sqrt(self)
    }
}

impl Sqrt for Z64 {
    fn sqrt(self) -> Self {
        Z64::sqrt(&self)
    }
}

然后,您只需要所需的特征即可。

use std::ops::{Add, Mul, Sub};

fn calc<T>(k1: T, k2: T, k3: T) -> (T, T)
where
    T: Add<Output = T> + Mul<Output = T> + Sub<Output = T> + Sqrt + Copy
{
    let a = k1 + k2;
    let b = k2 * k3.sqrt();
    (a + b, a - b)
}

如果您在许多地方使用这些相同的界限,请consider making a trait that requires all of them and a universal bound