loops - How can this loop be turned into idiomatic Rust?
问题描述
Here is a working Rust function:
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. It indexes into arrays using manually managed indices, pretty much like a for
loop in C.
Is there a way to achieve the same result using Rust iterators? I think chunked_exact
would work for iterating over src
, but what about dst
? What iterator could I zip
with src.chunked_exact
to write into dst
in chunks?
解决方案
什么是“惯用”可能是一个见仁见智的问题,但您可以使用更多的迭代器方法,例如zip
and 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
}
我使用chunks_exact
andchunks_exact_mut
而不是chunks
因为它保证切片具有请求的长度,如果您需要它们可以单独使用。这似乎与您的原始代码相匹配,它将长度四舍五入到确切的步数。
推荐阅读
- c++ - 如果内存不足,则抛出 bad_alloc
- c# - 在 IEnumerable 上使用 ToList() 方法
这已经是一个列表 - django - 如何修复错误“'ManyRelatedManager' 对象没有属性 'field_name'”
- jquery - jQuery:点击正文,如果选择器是那么
- javascript - 无法在新的 HttpRequest 处读取未定义的属性“indexOf”
- reactjs - 在反应应用程序上运行纱线测试时如何摆脱“运行所有测试的意外无效模式”警告
- javascript - [未处理的承诺拒绝:TypeError:f 不是函数。(在 'f()' 中,'f' 未定义)]
- php - 从子主题中的父主题中删除钩子函数
- game-physics - 我目前正在 Phaser 2 的学校项目中工作。我有移动代码工作,但玩家无法与地图的第一层发生碰撞
- jsf - 如何在 Primefaces 组件中使用 Material Icons 图标