接受多种数字类型的 Trait 对象的方法

Trait object's method which accepts several numeric types

我想要一个 trait 对象的方法,它接受多种数字类型,所有这些类型都将被转换为 f64。以下不编译,因为 NumCast 实现了 Sized 特性:

use num_traits::NumCast;

pub trait Grapher {
    fn add(&mut self, key: &str, number: &dyn NumCast);
    fn show(&self);
}

此类方法的通用版本禁用 Grapher 对象创建:

fn agregar<T: NumCast>(&mut self, key: &str, number: &T);

我的解决方案是创建另一个特征:

pub trait F64Convertible {
    fn convert(&self) -> f64;
}

impl F64Convertible for i32 {
    fn convert(&self) -> f64 {
        *self as f64
    }
}

impl F64Convertible for u8 {
    fn convert(&self) -> f64 {
        *self as f64
    }
}
// same for many numeric types...

// use the trait:
pub trait Grapher {
    fn add(&mut self, key: &str, number: &dyn F64Convertible);
    fn show(&self);
}

我想避免在我的代码中使用重复的转换函数,也许可以利用 NumCast 或类似的特性。

我认为在这种特殊情况下,接受 dyn NumCast 并没有多大帮助,因为 NumCast 只有一个 fn from(self) 从另一个数构造一个新数(而你可能想提供一个数字)。

现在,在这个例子中,你可能只需要 require ToPrimitive:

fn add(&mut self, key: &str, number: &dyn ToPrimitive) {
    number.to_f64();
}

但在采用该解决方案之前,我会问自己,如果您的函数只接受 Option<f64>(甚至 f64),是否不会让事情变得更简单。这样,很明显您的函数实际上可以在 f64 上运行,调用者只需要知道这一点。此外,简单地接受函数实际需要的类型涉及在调用站点进行一些强制转换,但通常会导致 运行 时间的强制转换较少。