我正在编写一个编码库,我想将slice
转换为usize
。
我看到一个read_uint
方法看起来很有希望,尽管我不确定如何将寄存器大小作为变量获取,因此可以将其放入函数中。
例如,我想在32位处理器上获得32
,在64位处理器上获得64
。
答案 0 :(得分:3)
一种方法是使用mem::size_of
获得usize
的大小:
use byteorder::{ByteOrder, ReadBytesExt};
fn read_usize<B, R>(mut b: R) -> Result<usize, std::io::Error>
where
B: ByteOrder,
R: ReadBytesExt,
{
b.read_uint::<B>(std::mem::size_of::<usize>()).map(|v| v as usize)
}
另一种是针对不同的体系结构具有不同的功能或功能实现:
fn read_usize<B, R>(mut b: R) -> Result<usize, std::io::Error>
where
B: ByteOrder,
R: ReadBytesExt,
{
if cfg!(target_pointer_width = "64") {
b.read_u64::<B>().map(|v| v as usize)
} else if cfg!(target_pointer_width = "32") {
b.read_u32::<B>().map(|v| v as usize)
} else {
b.read_u16::<B>().map(|v| v as usize)
}
}
另请参阅:
答案 1 :(得分:3)
TL; DR有一个不提供read_usize
函数的充分理由,因为它在不同的cpu架构上不一致。
这是一个坏主意。通常,您要尝试反序列化某种协议。此格式应独立于cpu架构,因此您不能读取usize,因为它取决于cpu。
我们假设您有一个简单的协议,首先要拥有一个数组的大小,然后是n
个元素。
+------+---------+
| size | ....... |
+------+---------+
让我们假设该协议说您的大小为4字节长。现在,您要执行Shepmaster建议的操作,并阅读取决于您的体系结构的usize。
在x86_64操作系统上,您现在将读取8个字节,因此吞噬了数组中的第一个元素。
在Atmega8上,您的大小为2个字节,因此仅占用您大小的前2个字节(如果少于65k的元素和BigEndian字节顺序,则为零)。
这就是为什么没有read_usize
函数并且它是正确的原因。您需要确定大小,从片中读取确切的字节数,然后我们as
将其转换为usize
。