我想将一个Vec
复制到另一个中,在[u8; 4]
的块中,只分配每个块的第一个3元素(不分配第四个(。这似乎是一种实用的方法:
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元素将被省略,并且可以从剩余部分中检索迭代器的函数。
由于每个chunk都有chunk_size元素,编译器可以通常会比块的情况更好地优化生成的代码。
所以。。。似乎是在说ChunksExactMut
(从chunks_exact_mut
返回(的元素大小是精确的,在这种情况下4,那么给出了什么呢?在编译时知道大小感觉就像是ChunksExactMut
的点。
我是不是搞错了?有没有更惯用的方法可以复制到ChunksExactMut
的切片中。我可以简单地用循环复制元素,但这看起来很臭。或者,是的方法,我应该让编译器来做这项工作?
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])
}