对不可变数组切片的引用的反向顺序

时间:2017-04-16 10:57:00

标签: rust borrow-checker

我想颠倒切片的顺序:

&[1, 2, 3] -> &[3, 2, 1]

这是我的代码:

fn iterate_over_file(data: &[u8], ...) -> ... {
    ...
    for cur_data in data.chunks(chunk_size) {
         let reversed_cur_data = cur_data.reverse() // this returns ()
         ...
    ...
 }

data参数来自我使用FileBuffer读取的文件,我想将其保留为引用切片(而不是将其转换为拥有的Vec,因为这是一个繁重的计算。)

如何以最少的操作和内存分配来反转cur_data的顺序?它的长度以我的程序的特定运行时(在此称为chunk_size)而闻名,但它在不同的运行之间发生变化。 reversed()似乎返回(),这是有意义的,因为它是就地完成的,我只有一个引用的切片。 .iter().rev()创建一个迭代器,但是我必须多次调用它.next()才能得到切片,这既不优雅又无效,因为我至少有数千万每个文件cur_data行。

1 个答案:

答案 0 :(得分:5)

reverse不仅会返回(),还需要一个您没有的可变切片。最佳解决方案完全取决于您需要对数据执行的操作。如果您只需要迭代数据,cur_data.iter().rev()就是正确且最有效的选择。

如果您需要切片内的反转数据,进行进一步处理,或将反转的块发送到需要切片的函数,您可以将数据收集到一个向量中,该向量在循环迭代之间预先分配和共享避免为每个块分配:

let mut reversed = Vec::new();
for cur_data in data.chunks(chunk_size) {
     // truncate the slice at the beginning of each iteration.
     // Vec explicitly guarantees that this will *not* deallocate,
     // it will only reset its internal length. An allocation will
     // thus happen only at the first loop iteration.
     reversed.truncate(0);
     reversed.extend(cur_data.iter().rev());
     // &reversed is now the reversed_cur_data you need
     ...
}