1

I want to switch the direction of an iterator based on a boolean parameter. I tried the following approach, but it ends with a compile error:

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6];

    print(&numbers, false);
    print(&numbers, true);
}

fn print(what: &[i32], reverse: bool) {
    let iter = what.iter();

    if reverse {
        iter = iter.rev();
    }

    for n in iter {
        println!("{n}");
    }
}

This is the error I receive:

// Error:
mismatched types
expected struct `std::slice::Iter<'_, _>`
   found struct `Rev<std::slice::Iter<'_, _>>`

How could I implement my desired behavior?

E_net4
  • 27,810
  • 13
  • 101
  • 139
finn
  • 653
  • 3
  • 15

1 Answers1

1

You can do it using dynamic dispatch as explained here like so:

fn iterateMyData(a: &mut VecDeque<A>, b: &mut BTreeMap<u64, VecDeque<B>>) {
    // Do something.

    let reverse: bool = a.front().unwrap().reverse;

    for a_value in a.iter_mut() {
        let mut temp_iter1;
        let mut temp_iter2;
        let mut iter: &mut dyn Iterator<Item = _> = if reverse {
            temp_iter1 = b.values_mut().rev();
            &mut temp_iter1
        } else {
            temp_iter2 = b.values_mut();
            &mut temp_iter2
        };
        
        for b_vec in iter {
            // Do something.
        }
    }
}

and the rustexplorer link.

However as already noted in the linked thread above, it is probably easier and better to use an enum (crate) like either like so

let mut iter =
    if reverse { 
        Either::Left(b.values_mut().rev()) 
    }
    else { 
        Either::Right(b.values_mut()) 
    };

Also in the case that you just need to print out the iterator in a certain direction based on a flag this can be done without external crates as follows:

fn main() {

    let numbers = vec![1, 2, 3, 4, 5, 6];

    print(&numbers, false);
    print(&numbers, true);
        
}

fn print(what: &[i32], reverse: bool) {
    //match statement condition check
    match reverse {
        true => {
            for n in what.iter().rev() {
                println!("{n}");
            }
        },
        false => {
            for n in what.iter() {
                println!("{n}");
            }
            
        },
    }
}
Logan
  • 5
  • 1
frankenapps
  • 5,800
  • 6
  • 28
  • 69