将半字节转换为u64最合适的方法是什么?

sam*_*moz 7 rust

我正在尝试学习Rust并决定编写一个将十六进制字符串转换为u64的程序.

目前,我已经将字符串解析为u8值的向量,每个值代表四位(或"半字节").我编写了以下代码来获取Vec<u8>并返回相应的代码u64.它的工作原理(据我的测试显示),但我不确定这是否是Rust的"适当"方式.

fn convert_nibbles_to_u64(values: &Vec<u8>) -> u64 {
    // We need to turn this buffer into a u64 now
    let mut temp:u64 = 0;
    for i in values {
        temp = temp << 4;

        unsafe {
            // We need to unsafely convert a u8 to a u64. Note that
            // the host endian-ness will matter here.
            use std::mem;
            let i_64_buffer = [0u8,0u8,0u8,0u8,0u8,0u8,0u8,i.clone()];
            let i_64 = mem::transmute::<[u8; 8], u64>(i_64_buffer);
            let i_64_be = u64::from_be(i_64);
            temp = temp | i_64_be;           
        }
    }
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

我想主要的问题是我不知道如何u8u64值转换成值.您能评论一下以更惯用的Rust风格改进或编写代码的方法吗?

编辑:我已尝试以下(不成功)替代不安全的块:

或者i作为u64:

temp = temp | i as u64; 
------
Compiler error:
main.rs:115:23: 115:31 error: non-scalar cast: `&u8` as `u64`
main.rs:115         temp = temp | i as u64;
Run Code Online (Sandbox Code Playgroud)

i直接:

temp = temp | i;
------
Compiler error:
main.rs:115:16: 115:24 error: the trait `core::ops::BitOr<&u8>` is not implemented for the type `u64` [E0277]
main.rs:115         temp = temp | i;
Run Code Online (Sandbox Code Playgroud)

Chr*_*gan 9

您的问题很简单:for i in valuesvalues类型中&Vec<u8>,迭代对每个值的引用 ; 也就是说,i是类型&u8.Oring和添加等参考文献没有意义; 你需要取消引用它,获得底层u8.最简单的方法是将其写入for循环模式(对于for语法for PATTERN in EXPRESSION,如果需要,请参考模式文档以获得更多解释;对于这个简单的情况,for &x in y { … }基本上意味着for x in y { let x = *x; … }):

fn convert_nibbles_to_u64(values: &[u8]) -> u64 {
    let mut out = 0;
    for &i in values {
        out = out << 4 | i as u64;
    }
    out
}
Run Code Online (Sandbox Code Playgroud)

循环的整个形式也可以使用Iterator.fold,如下所示:

fn convert_nibbles_to_u64(values: &[u8]) -> u64 {
    values.iter().fold(0, |x, &i| x << 4 | i as u64)
}
Run Code Online (Sandbox Code Playgroud)