如何将 [u64;N] 转换为 [u8;8*N]?

Axe*_*sen 3 rust

我正在用 Rust 编写一个压缩算法。

我有一个“转换表”,它将输入字节映射到输出(每个输出是一个u64代码,一个u8是代码的长度,不需要是8的倍数)。对于每个输入字节,我找到相应的输出并将代码位移到一个大的连续数组中u64。然后我想将这个 s 数组写入u64一个文件。

[u64; WRITE_CHUNK_SIZE]将 转换为 a 的最佳方法是什么[u8; 8 * WRITE_CHUNK_SIZE]

循环遍历[u64; WRITE_CHUNK_SIZE]、调用to_be_bytes()每个u64、将每个字节写入到[u8; 8*WRITE_CHUNK_SIZE]我能做的最好的事情吗?

我看到了align_to需要不安全的示例,这对于转换数据类型来说似乎太过分了。我还看到了输出一个Vec. 不过,我认为这只是把问题推到了路上,因为我仍然必须将其转换Vec<u8>[u8]写入文件。我错了吗?

Kev*_*eid 6

bytemuck板条箱提供了将一种类型重新解释为另一种类型的函数unsafe,只要这是安全的,因为这两种类型都是 \xe2\x80\x9cjust bytes\xe2\x80\x9d (没有无效值,也没有填充)。只需调用bytemuck::cast在任何整数数组类型之间进行转换,只要两种类型的总大小相同即可。(或者,bytemuck::cast_slice如果您有一个整数切片或整数数组。)

\n

此类转换纯粹是更改类型,因此没有运行时成本。但是,它们不会将字节重新排序为特定的字节顺序,因此这会暴露您正在运行的计算机的本机字节顺序。对于您的情况,也许您可​​以重新排列表来比显式交换字节更有效地解决此问题。如果你不能,那么可能to_be_bytes在循环中就已经是最好的了。

\n
const WRITE_CHUNK_SIZE: usize = 4;\n\nfn main() {\n    let sixtyfours: [u64; WRITE_CHUNK_SIZE] = [1, 2, 3, 0x0102030405060708];\n    let eights: [u8; 8 * WRITE_CHUNK_SIZE] = bytemuck::cast(sixtyfours);\n    println!("{:?}", eights);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这会打印(在小端机器上):

\n
[1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1]\n
Run Code Online (Sandbox Code Playgroud)\n