2017-07-15 71 views
0

我有下面的代码:如何迭代字符列表,同时仍能够在迭代中跳过?

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循环在这里,因为我有时需要跳过一个char在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 
+0

'字符数<>'是一个迭代器,而不是一个集合,所以你不能索引它这样反正。 – ildjarn

+1

当你想跳过一个字符时,只需使用'continue' ... – Boiethios

+0

我确实已经注意到了这一点,但这是我想出的一段代码,以说明我正在寻找的行为类型。 – duck

回答

6

这是更好地遍历的东西,而不是使用索引:

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

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

我们fuse迭代器,以避免任何问题后先调用next返回None


代码有一些问题:

  1. Iterator::count消耗的迭代器。一旦你调用它,迭代器就是不见了。这是你错误的原因。另一种解决方案是使用Iterator::by_ref,以便消耗您计算的迭代器不是行结束。

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

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

2

可以使用strcursor箱子此:

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`