【问题标题】:How do I cast a u64 value to a generic numeric type?如何将 u64 值转换为通用数字类型?
【发布时间】:2015-03-13 21:06:25
【问题描述】:

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

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

并让它在语义上表现得像259u64 as u8,即它应该只占用最低有效位。不幸的是,FromPrimitive::from_u64 函数返回一个Option&lt;T&gt;,如果输入值不合适,则返回None

这里有效:

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

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

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

【问题讨论】:

  • 为什么要将它作为一个单独的函数? v as u8 可以满足您的需求,如果您需要它作为函数,那么 |v| v as u8 可以正常工作。
  • @Chris:上面的函数当然只是我想做的事情的本质——或者我应该发布2000+行代码吗?我不能写v as u8 因为u8 只是一个例子。相信我,我需要转换为泛型类型,而不是特定类型。
  • 根据给定的请求,很难理解整个问题的目的,为什么需要这个函数。多一点可能会有所帮助。
  • 我的问题的确切上下文超出了问题的范围,并且不是真正需要的解决方案。但如果您有兴趣:我开发用于形式验证的软件并希望使用查找表来模拟布尔函数。为此,我有一个包含 6 个 u64 值的模板,这些值必须被截断为相应数量的布尔输入所需的长度(例如,u16 用于 4 个输入)。

标签: rust


【解决方案1】:

一种特别有效的方法是定义你自己的特质和想要的效果;尤其是如果您要处理更复杂的事情,这通常是您想要的(尽管绝对不是总是如此)。对于这种情况,您可能会选择这样的方法:

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::&lt;T&gt; 将是&lt;T as FromU64&gt;::from_u64,或者

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

【讨论】:

  • 谢谢,这是一个非常典型的解决方案!
猜你喜欢
  • 2015-07-23
  • 2017-01-22
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多