Sorry I could not find a better title for this question.
What I am trying to do is store a type which implements IntoIterator in a field and get Iterator from it when required (in pop function here). Problem is that self is this method is mutably borrowed when calling into_iter throws error.
I understand why the error is thrown but cannot resolve it.
Usually you would store the iterator I in the struct, not the IntoIterator type, since there isn't much you can do with an IntoIterator. The new function would then call into_iter(). In the playground you don't use the IntoIterator besides the pop. For what do you need the IntoIterator?
If you're trying to pop an item from the end of the Vec, you can just call Vec::pop. If that's not what you want to do, please describe what you want in as much detail as possible. It looks like you're unfamiliar with Rust ownership and Iterators, so you probably have a misunderstanding.
Well I want to rewind and and start from the start. Since Iterators cannot go back, I am storing a IntoIterator so that calling its into_iter function gets me a fresh iterator to use.
As you might have guessed I am just starting out and may be this is the wrong way to think.
If you have the Vec d available, you can call d.iter() any number of times to iterate over its elements by reference. So to reset to the beginning, you can just get a fresh iterator. Then you don't need the Retract type, and you don't need to use IntoIterator at all. (You may already know this, but I mention it just in case you don't.)
Another thing that looks like it could be a mistake is that you're storing references to integers in the Vec rather than just storing integers:
let d = vec![&1, &2, &3];
This may be a simplification of something you need to do, or it may be a misunderstanding about owned values. Can you describe why you used references here?
If you have the Vec d available, you can call d.iter() any number of times to iterate
Data is in a slice which does not have iter. I mean I could wrap the slice in a Vec but do not think that's good solution.
Can you describe why you used references here?
This is a mistake. Vec should be storing integers not references.
This Retract is part of a lexer and I want to use it to look ahead characters when determining tokens. If a set of characters does not match a particular Token, it would retract and check the same set of characters for another token.
Slices do have an iter method. And a Vec is automatically dereferenced to a slice, so in either case you can simply do d.iter() to get an iterator over the elements.
Ok.
I suggest showing that code. I have not written a lexer, but I'm sure others will have suggestions for how to do this.
However, I can say that you can easily iterate over the same slice twice using slice::iter.
I did not really understood what you were trying to achieve, but you might find these tips useful.
If you store the data your lexer need in Vec, you can get slice of this data by doing data[1..10] (or data.get(1..10) if you don’t want to panic on out-of-bounds) and then calling .iter() on it. This way you can iterate over all items in some range. This is probably what you wanted to do in linked example.
Other useful thing is to use enumerate() method on iterator, which will provide you with number of iterations. If you iterate over a slice, this will allow you to index it if you need while being able to use iterators. I used this myself then making a parser for terminal input.
struct Retract<I> {
last_commit: I,
current: I,
}
impl<I> Retract<I>
where
I: Iterator + Clone,
{
// API design is slightly tricky here; my hope would be that
// with this `+ Copy` bound on the `IntoIterator`, we're usually
// ruling out the (otherwise surprisingly costly) cases where the Iterator
// owns a lot of values and/or memory and the `Clone` is way too expensive.
//
// Putting a `Copy` bound on `I` itself wouldn't work,
// since iterators conventionally almost never implement `Copy`, anyway
pub fn new(into_iter: impl IntoIterator<IntoIter = I> + Copy) -> Self {
let i = into_iter.into_iter();
Self {
last_commit: i.clone(),
current: i,
}
}
pub fn pop(&mut self) -> Option<I::Item> {
self.current.next()
}
pub fn commit(&mut self) {
self.last_commit = self.current.clone();
}
pub fn retract(&mut self) {
self.current = self.last_commit.clone();
}
}
fn main() {
let d = vec![1, 2, 3];
let r = Retract::new(&d);
}