2015-03-13 28 views
1

我想一个U64值转换为普通的数字型,有点像如何将u64值转换为通用数值类型?

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

并将其行为语义等,例如,259u64 as u8,即,它应该只取最显著位。不幸的是,FromPrimitive::from_u64函数返回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等整数类型感兴趣,没有时髦的东西。

+0

为什么你想它作为一个单独的功能? 'v as u8'就能满足你的要求,如果你需要它作为函数,那么'| v | v作为u8'将正常工作。 – 2015-03-13 07:04:30

+0

@Chris:上面的函数当然只是我想要做的事情的本质 - 或者我应该发布2000多行代码?我不能写'v as u8',因为'u8'只是一个例子。相信我,我需要转换为泛型类型,而不是特定类型。 – 2015-03-13 07:44:15

+0

根据给出的要求,很难理解整个问题的目的*,为什么需要这个功能。多一点可能会有所帮助。 – 2015-03-13 12:42:41

回答

2

特别有效地做到这一点的一种方法是定义你自己的特质与所需的效果;特别是如果你遇到更复杂的事情,这通常会成为你的愿望(尽管绝对不总是)。对于这种情况,你可能会去这样的事情:

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) 
} 
+0

谢谢,这是一个非常具有代表性的解决方案! – 2015-03-13 16:26:23

相关问题