使用 for 循环迭代切片时跳过元素

Hea*_*ery 6 iterator for-loop rust

在 Rust 中,如何在for样式循环中执行可变大小的步骤?我可以使用此构造执行固定大小的步骤:

for i in (0..vals.len()).step_by(4)
{
    println!("{}: {}", i, vals[i]);
}
Run Code Online (Sandbox Code Playgroud)

或者更合适的:

for (i,val) in vals.iter().enumerate().step_by(4)
{
    println!("{}: {}", i, val);
}
Run Code Online (Sandbox Code Playgroud)

但我真正想做的是:

for i in 0..vals.len()
{
    println!("{}: {}", i, vals[i]);
    if      vals[i] == 1 { i += 2; }
    else if vals[i] == 2 { i += 4; }
}
Run Code Online (Sandbox Code Playgroud)

但当然,修改i不会影响循环迭代器。

由于主要具有 C 语言背景,现代语言对迭代器的依赖常常让人感觉像是戴着手套进行编程。通常谷歌会来救援,但我还没有找到任何解决方案来解决这个看似相当简单的问题。

我想出的最好的是

let mut i:usize = 0;
while i < vals.len()
{
    println!("{}: {}", i, vals[i]);
    if      vals[i] == 1  { i += 2; }
    else if vals[i] == 2  { i += 4; }
}
Run Code Online (Sandbox Code Playgroud)

但这感觉就像一个穷人的for循环,与我应该做的利用配备迭代器的语言相反。是否有跳过迭代的变体,或者从循环内调用迭代器的continue方法?skip

Luk*_*odt 5

确实没有更好的选择。我仍然可以想到这一点:

let mut skip = 0;
for (i, val) in vals.iter().enumerate() {
    if skip > 0 {
        skip -= 1;
        continue;
    }

    println!("{}: {}", i, val);

    skip = match val {
        1 => 2,
        2 => 4,
        _ => 0,
    };
}
Run Code Online (Sandbox Code Playgroud)

但这并不一定比您已有的想法更好。

之所以没有“好的”解决方案,是因为这种用例非常罕见。for循环适用于完全迭代迭代器的常见情况。对于需要一些更复杂的“高级迭代器”逻辑的情况,while循环loop可以满足您的需要。这些循环并不“糟糕”,它们正是针对这些情况。

我认为你的while循环解决方案非常好!