如何将一片字节(& [u8])的缓冲区转换为整数?

时间:2015-03-27 18:11:32

标签: arrays casting rust slice

我正在从文件中读取原始数据,我想将其转换为整数:

fn main() {
    let buf: &[u8] = &[0, 0, 0, 1];
    let num = slice_to_i8(buf);
    println!("1 == {}", num);
}

pub fn slice_to_i8(buf: &[u8]) -> i32 {
    unimplemented!("what should I do here?")
}

我会在C中进行类型转换,但是我在Rust中做什么?

3 个答案:

答案 0 :(得分:21)

我建议使用byteorder crate

use byteorder::{BigEndian, ReadBytesExt}; // 1.2.7

fn main() {
    let mut buf: &[u8] = &[0, 0, 0, 1];
    let num = buf.read_u32::<BigEndian>().unwrap();

    assert_eq!(1, num);
}

这会处理奇数大小的切片并自动推进缓冲区,以便您可以读取多个值。

从Rust 1.32开始,您还可以对整数使用from_le_bytes / from_be_bytes / from_ne_bytes固有方法:

fn main() {
    let buf = [0, 0, 0, 1];
    let num = u32::from_be_bytes(buf);

    assert_eq!(1, num);
}

这只处理已知大小的数组,以避免在数据不足时处理错误。

另见:

答案 1 :(得分:1)

我想在此给出此答案,以提交以下其他详细信息:

  1. 有效的代码片段,可将 slice 转换为整数(两种方式)。
  2. no_std环境中有效的解决方案。
  3. 将所有内容保存在一个地方,以方便人们从搜索引擎到达这里。

在没有外部包装箱的情况下,即使对于从Rust 1.32开始的no_std构建,以下方法也适用于将 切片 转换为整数:

方法1(try_into + from_be_bytes

use core::convert::TryInto;

let src = [1, 2, 3, 4, 5, 6, 7];

// 0x03040506
u32::from_be_bytes(src[2..6].try_into().unwrap());

use core::conver::TryInto用于no_std构建。使用标准板条箱的方式如下:use std::convert::TryInto;

(关于字节序,已经回答了,但是让我将其放在一个位置:from_le_bytesfrom_be_bytesfrom_ne_bytes-根据整数的表示方式使用它们在内存中)。

方法2(clone_from_slice + from_be_bytes

let src = [1, 2, 3, 4, 5, 6, 7];
let mut dst = [0u8; 4];

dst.clone_from_slice(&src[2..6]);

// 0x03040506
u32::from_be_bytes(dst);

结果

在两种情况下,整数都将等于0x03040506

答案 2 :(得分:0)

此自定义serialize_deserialize_u8_i32库将在u8数组和i32数组之间安全地来回转换,即序列化函数将获取您的所有u8值并将其打包为i32值,而deserialise函数将获取此库的自定义i32值并进行转换回到最初的u8值。

它是为特定目的而构建的,但是对于其他用途可能会派上用场;取决于您是否想要这样的快速/自定义转换器。

https://github.com/second-state/serialize_deserialize_u8_i32