Rust中的通用函数是否具有有限的已知类型?

时间:2016-08-22 08:33:21

标签: generics types rust

我在Rust中编写了一些代码,它们与f64f32一样可以正常工作。

尝试将其转换为使用泛型函数非常复杂;我需要在每次使用时声明该类型的功能。

实际上,我只想使用f32f64。有没有办法编写仅适用于一组已知类型的泛型函数?

我意识到这有点违背了泛型函数。

3 个答案:

答案 0 :(得分:3)

只需使用the Float trait from the num crate即可。只有f32f64 ,您才能拥有所需的一切。如果你真的不需要,不要写自己的特质。

只需将条箱num-traits添加到 Cargo.toml 文件的[dependencies]部分即可使用该特性:

[dependencies]
# ...
num-traits = "0.1"

答案 1 :(得分:2)

唯一想到的工具是trait,所以你的功能是:

pub fn f<T: MyTrait>(x: T) {...}

然后,您可以为MyTraitf32实施f64。这很接近,但是有一个漏洞:调用者可以在他们自己的类型上实现特征。你不能通过使MyTrait私有来解决这个问题,因为Rust会抱怨你在公共接口中使用私有类型(MyTrait)。

如此接近,但我认为这不可能!

虽然我同意关于使用现有相关特征的其他答案,但你会这样做:

mod foo {
    pub trait MyTrait {}
    impl MyTrait for f32 {}
    impl MyTrait for f64 {}

    pub fn f<T: MyTrait>(x: T) {}
}

pub fn main() {
    foo::f(3f32);
    foo::f(3f64);
    // foo::f(3u64);  // doesn't work as u64 doesn't implement MyTrait
}

答案 2 :(得分:0)

这可能不太理想,但我通过使用特征和宏来实现这一点。

例如,假设我们希望此功能采用f32f64

fn sqr(a: f32) -> f32 {
    a * a
}

我们可以先把它放在一个特性中:

trait Sqr {
    fn sqr(self) -> Self;
}

然后我们制作一个宏来实现它。宏只接受一个类型,并实现该类型的特征:

macro_rules! impl_sqr {
    ($t:ty) => (
        impl Sqr for $t {
            fn sqr(self) -> Self {
                self * self
            }
        }
    );
}

然后我们调用f32f64的宏:

impl_sqr!(f32);
impl_sqr!(f64);

Full example here.