Hi,
I want like to get the current item of an iterator where it points to.
I.e., in C++ I can increment an iterator with ++it and can retrieve the current value with *it. I couldn't find something similar in Rust.
How can I get the current item without calling iterator.rev() and then iterator.next()?
fn parse_string(&mut self, iterator: &mut Bytes) {
loop {
match iterator.next() {
Some(char) if char == b'"' => {
break;
},
// Do something else...
}
}
// Pseudo code!!!
if let Some(current_char) = iterator.current_item() {
// Do something
} else {
// Iterator has reached end. Do something else!
}
}
In Rust we either store the result of calling next() in a local variable (or this is done for us by using a for loop), or use a peekable iterator in cases where this isn't sufficient. There is a recent thread on the same topic.
Thank you, but peekable isn't exactly what I want, because I have to call peek() and then next() on different match cases. This would be error-prone and ugly.
And I also wanted to avoid having a local variable, but I seems I have to do this.
Strange, that such a basic thing isn't in the API and it seems to be a recurring topic...
If you can give a specific example where iterators and peekable are inconvenient, you'll get a whole bunch of suggestions. But in the code you posted, a local variable the most obvious solution.
In your peekable version it looks like you swapped your uses of next for peeks for some reason. A peekable iterator doesn't change the meaning of next, so don't do that. Instead, use peek where you would have used current_element.
- if None == iterator.current_element() {
+ if iterator.peek().is_none() {
Rust iterators don't describe a collection. They are a single-use-only stream of objects.
There may not be a current element, because elements can be computed on the fly, by an arbitrarily complex pipeline that is allowed to have side effects. Iterators may also return objects with exclusive access or unique ownership, so they can't safely hold on to the last object returned.
Peekable iterator reads one element ahead of time (which is an observable side effect), buffers it, and gives temporary access to the buffer.
You are not looking for the "current" element then, but the "last yielded" element. However since it was already yielded the iterator does not have ownership of it anymore, so it won't be able to give it to you.
Well, I clearly compared it with C++ iterator. *it yields the current element. It is a dereference of the current pointer. peek() would be *(it+1) which is something different.
Okay, then I got it right, that this is just not possible with Rust.