【问题标题】:How do I iterate over a list of chars while still being able to skip in the iteration?如何迭代字符列表,同时仍然能够在迭代中跳过?
【发布时间】:2017-07-15 20:25:53
【问题描述】:

我有以下代码:

let mut lex_index = 0;
let chars = expression.chars();
while lex_index < chars.count() {
    if(chars[lex_index] == "something") {
        lex_index += 2;
    } else {
        lex_index += 1;
    }
}

我在这里使用while 循环,因为有时我需要跳过chars 中的字符。 但是,这给了我以下错误:

error[E0382]: use of moved value: `chars`
  --> src/main.rs:23:15
   |
23 |     while i < chars.count() {
   |               ^^^^^ value moved here in previous iteration of loop
   |
   = note: move occurs because `chars` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait

【问题讨论】:

  • Chars&lt;&gt; 是一个迭代器,而不是一个集合,所以无论如何你都不能这样索引它。
  • 当你想跳过一个字符时,只需使用continue...
  • 我确实注意到了这一点,但这是我想出的一段快速代码来说明我正在寻找的行为类型。

标签: while-loop rust iteration chars


【解决方案1】:

最好迭代一些东西而不是使用索引:

let mut chars = "gravy train".chars().fuse();

while let Some(c) = chars.next() {
    if c == 'x' {
        chars.next(); // Skip the next one
    }
}

我们fuse 迭代器以避免在第一个None 返回后调用next 出现任何问题。


您的代码存在许多问题:

  1. Iterator::count 使用迭代器。一旦你调用了它,迭代器就消失了。这就是你的错误的原因。另一种解决方案是使用Iterator::by_ref,这样就不会消耗您计数的迭代器。

  2. chars 的类型为 Chars,不支持索引。 chars[lex_index] 毫无意义。

  3. 您不能将char 与字符串进行比较,因此chars[lex_index] == "something" 也不会编译。有可能你可以使用Chars::as_str,但你必须放弃Fuse 并自己处理。

【讨论】:

  • 根据我对doc.rust-lang.org/std/str/struct.Chars.html 的解释,Chars 迭代器已经融合。根据文档,在已经融合的运算符上调用 fused() 没有任何效果,也不会导致性能损失。您是否有意使用“.fuse()”?也许图书馆的这方面自 2017 年 7 月 15 日以来已经更新。
  • @hddh 你基本上已经回答了你自己的问题:在已经融合的运算符上调用fused() 没有任何效果,也不会导致性能损失。当您需要在迭代器返回一次 None 后调用 next 时,请始终调用 fuse
【解决方案2】:

您可以为此使用strcursor crate:

extern crate strcursor;

fn main() {
    use strcursor::StrCursor;
    let expr = r"abc\xdef";
    let mut cur = StrCursor::new_at_start(expr);

    // `after`: the next grapheme cluster
    while let Some(gc) = cur.after() {
        if gc == "\\" {
            // Move right two grapheme clusters.
            cur.seek_next();
            cur.seek_next();
        } else {
            print!("{}", gc);
            cur.seek_next();
        }
    }
    println!("");
}

// Output: `abcdef`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 2022-01-22
    • 2019-06-07
    • 2021-12-15
    • 2017-03-18
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多