为什么 Rust 的 ChunksExact<T> 在编译时没有已知的大小

Why doesn't Rust's ChunksExact<T> have a size known at compile-time

我想将一个 Vec 复制到另一个,在 [u8; 4] 中分配第一个 3 仅每个块的元素(仅保留第 4 个)。这似乎是一种实用的方法:

    let input_pix: Vec<u8> = ...;
    let mut output_pix: Vec<u8> = vec![255; input_pix.len()];
    for (input_chunk, output_chunk) in input_pix.chunks(4).zip(output_pix.chunks_exact_mut(4)) {
       let i: u8 = foo(...);
       output_chunk[0..2].clone_from_slice([i,3]);
    }

...但是 编译器不喜欢它。事实上 slicing output_chunk 完全会抛出错误。最简单:

        ...
        for (input_chunk, output_chunk) in input_pix.chunks(4).zip(output_pix.chunks_exact_mut(4)) {
           let s = format!("{:?}", output_chunk[0..2]);
        }

结果...

    |
40  |         let s = format!("{:?}", output_chunk[0..2]);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

来自文档:

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks.

所以...似乎是说 ChunksExactMut(从 chunks_exact_mut 返回)的元素大小是准确的,在这种情况下 4,那又是什么呢?在编译时知道大小感觉有点像 of ChunksExactMut.

我走错路了吗?是否有一些更惯用的方法来复制到 ChunksExactMut 的一片中。我可以简单地通过循环复制元素,但这看起来很臭。或者也许做这件事的方法,我应该让编译器完成工作?

TL;DR: 只需将其更改为

let s = format!("{:?}", &output_chunk[0..2]);
//                     ^^^ the important bit

按范围索引切片(&[T] 类型)时,return 类型为 [T]。调整大小是 属性 类型而不是 属性 值。因此,即使我们使用已知宽度(即 0..2)进行索引,我们仍然会得到一个未调整大小的类型作为输出。

未调整大小的一个缺点是该类型的值无法传递给函数。因此,为了将这种类型的元素格式化为字符串,我们必须传递一个指针。最简单的方法就是简单地借用切片。

无效:

fn foo(slice: &[u8]) -> String {
    format!("{:?}", slice[0..2])
}

有效:

fn foo(slice: &[u8]) -> String {
    format!("{:?}", &slice[0..2])
}