Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass an iterator I am iterating on to a function?

Tags:

iterator

rust

I'm iterating through an array, and depending on the current value, I'd like to pass the iterator to a sub function and have it deal with a number of values, and upon exiting the sub function, carry on iterating through the array. Below is the closest I've managed to get so far, but I keep getting error: use of moved value: 'iter'.

I've tried looking into lifetimes, but that hasn't worked for me either. I've spent most of a day on this now, and can't seem to get anywhere with it. Any help would be greatly appreciated. Thanks.

enum Thing {
    Three(char, char, char),
    Four(char, char, char, char),
}

fn take_three <'a>(iter: &mut std::slice::Iter<'a, char>) -> Thing {
    let a = iter.next().unwrap();
    let b = iter.next().unwrap();
    let c = iter.next().unwrap();
    Thing::Three(*a,*b,*c)
}

fn take_four <'a>(iter: &mut std::slice::Iter<'a, char>) -> Thing {
    let a = iter.next().unwrap();
    let b = iter.next().unwrap();
    let c = iter.next().unwrap();
    let d = iter.next().unwrap();
    Thing::Four(*a,*b,*c,*d)
}

fn parse_tokens (tokens: &Vec<char>) {
    let mut iter = tokens.iter();
    let mut things: Vec<Thing> = vec![];
    for token in iter {
        match token {
            &'a' => things.push(take_three(&mut iter)),
            &'b' => things.push(take_four(&mut iter)),
            _ => {},
        }
    }
}

fn main() {
    let tokens = vec!['a', '1', '2', '3', 'b', '1', '2', '3', '4', 'a', '4', '5', '6'];
    parse_tokens(&tokens);
}
like image 891
George Roger Avatar asked Mar 18 '23 01:03

George Roger


1 Answers

The for construct consumes the iterator, and doing what you want using it will be quite tricky (if not impossible, I'm really not sure about that).

However, you can have it working pretty easily by switching to a while let construct, like this:

fn parse_tokens (tokens: &Vec<char>) {
    let mut iter = tokens.iter();
    let mut things: Vec<Thing> = vec![];
    while let Some(token) = iter.next() {
        match token {
            &'a' => things.push(take_three(&mut iter)),
            &'b' => things.push(take_four(&mut iter)),
            _ => {},
        }
    }
}
like image 70
Levans Avatar answered Apr 01 '23 05:04

Levans