Reputation: 3
Apologies if this is long winded, I want to make myself as clear as I can be. Ok so here is what I would like this code to do:
What I thought I was doing was passing the iterator in exactly the state that it was in when I make the method call in main, but apparently this isnt happening, because while while let Some(value) = iterator.peek()
works in main, it doesnt work in the methods, It gives me "no method named peek found for type parameter impl Iterator<Item = &'a str> in the current scope"
fn main() {
let vector = vec!["skip", "value","value", "save","value", "skip", "value","value", "save", "value",];
let mut iterator = vector.iter().copied().peekable();
while let Some(value) = iterator.peek() {
match *value {
"skip" => {
iterator.next(); // Discarding the value we peeked at
skip_values(iterator.by_ref())
},
"save" => {
iterator.next(); // Discarding the value we peeked at
save_values(iterator.by_ref())
},
_ => (),
}
}
}
fn skip_values<'a>(mut iterator: impl Iterator<Item = &'a str>){
while let Some(value) = iterator.peek() { // Ensuring iterator is not empty
if value != "skip" && value != "save" {
iterator.next(); // discard value
} else {
break;
}
}
}
fn save_values<'a>(mut iterator: impl Iterator<Item = &'a str>){
while let Some(value) = iterator.peek() { // Ensuring iterator is not empty
if value != "skip" && value != "save" {
iterator.next(); // discard value
} else {
break;
}
}
}
And just to get ahead of this: This is just a simpler way of reproducing the error I am running into in my code. I know full well that if I actually wanted to accomplish the above behavior there are easier ways.
I have tried redeclaring the iterator as iterator.peekable(), but then I run into the issue that it says I am borrowing its value in a previous iteration of the loop.
In the simplest terms, I want to be able to loop through the iterator I pass into the method in a nearly identical way as I do in main.
I know that I am not consuming the entire iterator in main because I can still call next() on it in the method without issue.
Upvotes: 0
Views: 699
Reputation: 43962
For the functions to be able to peek, you need to declare their parameters as being Peekable
, not just an arbitrary iterator. This revision of your code compiles, with that and a few other tweaks to make the types line up:
use std::iter::Peekable;
fn main() {
let vector = vec!["skip", "value","value", "save","value", "skip", "value","value", "save", "value",];
let mut iterator = vector.iter().copied().peekable();
while let Some(value) = iterator.peek() {
match *value {
"skip" => {
iterator.next(); // Discarding the value we peeked at
skip_values(iterator.by_ref());
},
"save" => {
iterator.next(); // Discarding the value we peeked at
save_values(iterator.by_ref());
},
_ => (),
}
}
}
fn skip_values<'a>(iterator: &mut Peekable<impl Iterator<Item = &'a str>>){
while let Some(&value) = iterator.peek() { // Ensuring iterator is not empty
if value != "skip" && value != "save" {
iterator.next(); // discard value
} else {
break;
}
}
}
fn save_values<'a>(iterator: &mut Peekable<impl Iterator<Item = &'a str>>){
while let Some(&value) = iterator.peek() { // Ensuring iterator is not empty
if value != "skip" && value != "save" {
iterator.next(); // discard value
} else {
break;
}
}
}
Upvotes: 2