首页 > 解决方案 > 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?

标签: loopsrustiteratoridioms

解决方案


什么是“惯用”可能是一个见仁见智的问题,但您可以使用更多的迭代器方法,例如zipand 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_exactandchunks_exact_mut而不是chunks因为它保证切片具有请求的长度,如果您需要它们可以单独使用。这似乎与您的原始代码相匹配,它将长度四舍五入到确切的步数。


推荐阅读