How do I iterate over a list of chars while still being able to skip in the iteration?

若如初见. 提交于 2019-12-11 17:22:34

问题


I have the following piece of code:

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;
    }
}

I use a while loop here since I sometimes need to skip a char in chars. However, this gives me the following error:

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

回答1:


It's better to iterate over something instead of using an index:

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

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

We fuse the iterator to avoid any issues with calling next after the first None is returned.


Your code has a number of issues:

  1. Iterator::count consumes the iterator. Once you've called that, the iterator is gone. That's the cause of your error. An alternate solution is to use Iterator::by_ref so that consuming the iterator you count isn't the end of the line.

  2. chars is of type Chars, which does not support indexing. chars[lex_index] is nonsensical.

  3. You cannot compare a char to a string, so chars[lex_index] == "something" wouldn't compile either. It's possible you could use Chars::as_str, but then you'd have to give up Fuse and deal with that yourself.




回答2:


You can use the strcursor crate for this:

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`


来源:https://stackoverflow.com/questions/45122446/how-do-i-iterate-over-a-list-of-chars-while-still-being-able-to-skip-in-the-iter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!