我正在寻找一种通用机制,允许我获得给定整数类型的双精度版本
u8 -> u16
u16 -> u32
等等
在c++中,我们可以定义模板结构#include <cstddef>
using undefined = void;
template <class T>
struct double_precision {
using type = undefined;
};
template <class T>
using double_precision_t = typename double_precision<T>::type;
和添加专门化
template <>
struct double_precision<std::uint8_t> {
using type = std::uint16_t;
};
template <>
struct double_precision<std::uint16_t> {
using type = std::uint32_t;
};
template <>
struct double_precision<std::uint32_t> {
using type = std::uint64_t;
};
在之后得到双精度版本的double_precision_t<T>
,如
template<class T>
double_precision_t<T> square(T value) {
double_precision_t<T> double_precision_value = value;
return double_precision_value * double_precision_value;
}
我们如何在Rust中做类似的事情?
你可以使用traits:
trait DoublePrecision {
type Output: From<Self>;
}
impl DoublePrecision for u16 {
type Output = u32;
}
// etc...
然后按如下方式使用:
fn square<T: DoublePrecision>(value: T) -> T::Output
where
T::Output: std::ops::Mul<T::Output, Output = T::Output>
{
value.into() * value.into()
}
对于更复杂的用法,请参见num
trait向T
添加需求。
您可以使用一个trait和一些num
trait来使其相当通用:
use num::cast::AsPrimitive;
trait DoublePrecision: AsPrimitive<Self::Output> {
type Output: std::ops::Mul<Output = Self::Output> + Copy;
fn double_precision(self) -> Self::Output {
self.as_() * self.as_()
}
}
impl DoublePrecision for u8 {
type Output = u16;
}
fn main() {
assert_eq!(16, 4.double_precision());
}
你可以写一个小宏来写impl
块。