繁体   English   中英

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

[英]How to convert [u64;N] to [u8;8*N]?

我正在 Rust 中编写压缩算法。

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

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

正在循环[u64; WRITE_CHUNK_SIZE] [u64; WRITE_CHUNK_SIZE] ,在每个u64上调用to_be_bytes() ,将 this 的每个字节写入[u8; 8*WRITE_CHUNK_SIZE] [u8; 8*WRITE_CHUNK_SIZE]我能做到的最好吗?

我看到了需要不安全的align_to示例,这似乎只是为了转换数据类型。 我也看到了这个输出Vec 不过,我认为这只是将问题推到了后面,因为我仍然必须将Vec<u8>转换为[u8]才能写入文件。 我错了吗?

你可以使用bytemuck crate 提供的函数来将一种类型重新解释为另一种类型,而无需使用unsafe ,只要这是安全的,因为两种类型都是“只是字节”(没有无效值和没有填充)。 只需调用bytemuck::cast在任何 integer 数组类型之间进行转换,只要两种类型的总大小相同。 (或者,如果你有一个整数切片或 integer arrays, bytemuck::cast_slice cast_slice。)

这种转换纯粹是改变type ,因此它们没有运行时成本。 但是,它们不会将字节重新排序为特定的字节序,因此这会暴露您正在运行的机器的本机字节序。 在您的情况下,也许您可以重新排列表格以比显式交换字节更有效地解决这个问题。 如果你做不到,那么循环中的to_be_bytes可能会尽可能好。

const WRITE_CHUNK_SIZE: usize = 4;

fn main() {
    let sixtyfours: [u64; WRITE_CHUNK_SIZE] = [1, 2, 3, 0x0102030405060708];
    let eights: [u8; 8 * WRITE_CHUNK_SIZE] = bytemuck::cast(sixtyfours);
    println!("{:?}", eights);
}

这将打印(在 little-endian 机器上):

[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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM