1

我想将一个复制Vec到另一个中,仅分配每个块的前3元素(仅保留第 4 个元素)。这似乎是一种实用的方法:[u8; 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]);
    }

...但是编译器不喜欢它。事实上,切片 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

从文档:

块是切片并且不重叠。如果 chunk_size 不除切片的长度,那么最后的 chunk_size-1 个元素将被省略,并且可以从迭代器的剩余函数中检索。

由于每个块都有确切的块大小元素,编译器通常可以比块的情况更好地优化生成的代码。

所以...似乎是在说 a ChunksExactMut(从chunks_exact_mut)返回的元素的大小是精确的,在这种情况下是4,那么给出了什么?在编译时知道大小感觉就像.ChunksExactMut

我会以错误的方式解决这个问题吗?是否有一些更惯用的方法可以复制到ChunksExactMut. 我可以简单地用循环复制元素,但这看起来很臭。或者也许这就是这样做的方法,我应该让编译器完成这项工作?

4

1 回答 1

1

TL;DR:只需将其更改为

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

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

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

不起作用:

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

是否有效:

fn foo(slice: &[u8]) -> String {
    format!("{:?}", &slice[0..2])
}
于 2020-02-29T05:15:57.273 回答