我在Rust中编写了一些代码,它们与f64
和f32
一样可以正常工作。
尝试将其转换为使用泛型函数非常复杂;我需要在每次使用时声明该类型的功能。
实际上,我只想使用f32
和f64
。有没有办法编写仅适用于一组已知类型的泛型函数?
我意识到这有点违背了泛型函数。
答案 0 :(得分:3)
只需使用the Float
trait from the num crate即可。只有f32
和f64
,您才能拥有所需的一切。如果你真的不需要,不要写自己的特质。
只需将条箱num-traits
添加到 Cargo.toml 文件的[dependencies]
部分即可使用该特性:
[dependencies]
# ...
num-traits = "0.1"
答案 1 :(得分:2)
唯一想到的工具是trait
,所以你的功能是:
pub fn f<T: MyTrait>(x: T) {...}
然后,您可以为MyTrait
和f32
实施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)
这可能不太理想,但我通过使用特征和宏来实现这一点。
例如,假设我们希望此功能采用f32
或f64
:
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
}
}
);
}
然后我们调用f32
和f64
的宏:
impl_sqr!(f32);
impl_sqr!(f64);