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



我想将一个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])
}

相关内容

  • 没有找到相关文章

最新更新