[英]How can this loop be turned into idiomatic Rust?
Here is a working Rust function: 这是一个正常工作的Rust函数:
fn foo(src: &[u8]) -> Vec<u8> {
let dst_len = (src.len() / 3) * 4;
let mut dst = vec![0 as u8; dst_len];
let mut si = 0;
let mut di = 0;
let n = (src.len() / 3) * 3;
for _ in (0 .. n).step_by(3) {
let v = bar(src[si], src[si+1], src[si+2]);
dst[di+0] = baz(v, 0);
dst[di+1] = baz(v, 1);
dst[di+2] = baz(v, 2);
dst[di+3] = baz(v, 3);
si += 3;
di += 4;
}
dst
}
It works but that loop doesn't seem like idiomatic Rust. 它可以工作,但是该循环看起来不像惯用的Rust。 It indexes into arrays using manually managed indices, pretty much like a
for
loop in C. 它使用手动管理的索引索引到数组中,非常类似于C中的
for
循环。
Is there a way to achieve the same result using Rust iterators? 有没有一种方法可以使用Rust迭代器达到相同的结果? I think
chunked_exact
would work for iterating over src
, but what about dst
? 我认为
chunked_exact
可以在src
迭代,但是dst
呢? What iterator could I zip
with src.chunked_exact
to write into dst
in chunks? 我可以使用
src.chunked_exact
zip
哪些迭代器以成块地写入dst
?
What is "idiomatic" can be a matter of opinion, but you can make use of more iterator methods, like zip
and chunks_exact_mut
: 什么是“惯用的”可以是一个问题,但是您可以使用更多的迭代器方法,例如
zip
和chunks_exact_mut
:
fn foo(src: &[u8]) -> Vec<u8> {
let dst_len = (src.len() / 3) * 4;
let mut dst = vec![0 as u8; dst_len];
for (s, d) in src.chunks_exact(3).zip(dst.chunks_exact_mut(4)) {
let v = bar(s[0], s[1], s[2]);
d[0] = baz(v, 0);
d[1] = baz(v, 1);
d[2] = baz(v, 2);
d[3] = baz(v, 3);
}
dst
}
I used chunks_exact
and chunks_exact_mut
rather than chunks
because it guarantees that the slice has the requested length, making them available separately if you need them. 我使用
chunks_exact
和chunks_exact_mut
而不是chunks
因为它可以保证切片具有请求的长度,并在需要时使其分开可用。 This seems to match your original code, which rounds off the length to an exact number of steps. 这似乎与您的原始代码匹配,该代码将长度四舍五入为确切的步数。
I would go with that: 我会同意的:
fn foo(src: &[u8]) -> Vec<u8> {
src.chunks_exact(3)
.map(|s| bar(s[0], s[1], s[2]))
.flat_map(|v| (0..4).map(move |i| baz(v, i)))
.collect()
}
Or if you prefer: 或者,如果您愿意:
fn foo(src: &[u8]) -> Vec<u8> {
src.chunks_exact(3)
.map(|s| bar(s[0], s[1], s[2]))
.flat_map(|v| vec![baz(v, 0), baz(v, 1), baz(v, 2), baz(v, 3)])
.collect()
}
Not sure if you find one of them better. 不知道您是否找到更好的一种。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.