如何将 u64 值转换为通用数字类型?

How do I cast a u64 value to a generic numeric type?

我想将 u64 值转换为通用数字类型,例如

fn f<T: AppropriateTrait>(v: u64) -> T {
    v as T
}

并使其在语义上表现得像 259u64 as u8,即它应该只占用最低有效位。不幸的是,如果输入值不合适,FromPrimitive::from_u64 函数 returns 和 Option<T>None

这里有效:

fn f<T: FromPrimitive + Int + ToPrimitive>(v: u64) -> T {
    T::from_u64(v & T::max_value().to_u64().unwrap()).unwrap()
}

但它非常冗长和不雅。有没有更好的方法?

编辑:我只对转换为整数类型感兴趣,如 u8、u16 等,没有时髦的东西。

一种特别有效地做到这一点的方法是定义您自己的具有所需效果的特征;特别是如果您要处理更复杂的事情,这通常是您想要的(尽管并非总是如此)。对于这种情况,您可能会这样做:

trait FromU64 {
    fn from_u64(v: u64) -> Self;
}

macro_rules! impl_from_u64 {
    ($($ty:ty)*) => {
        $(
            impl FromU64 for $ty {
                #[inline]
                fn from_u64(v: u64) -> $ty {
                    v as $ty
                }
            }
        )*
    }
}

impl_from_u64!(u8 u16 u32 u64 usize);

您原来的 f::<T> 将是 <T as FromU64>::from_u64,或者

fn f<T: FromU64>(v: u64) -> T {
    FromU64::from_u64(T)
}