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
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:
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.
chars
is of type Chars
, which does not support indexing. chars[lex_index]
is nonsensical.
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.
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`