1

I want have something like below

use std::collections::HashMap;

pub enum DiffStruct {
    V(Vec<i32>),
    M(HashMap<i32,i32>),
}

impl DiffStruct {
    fn to_iter(self) -> impl IntoIterator<Item = i32> {
        match self {
            DiffStruct::V(vec) => vec.iter().into_iter(),
            DiffStruct::M(map) => map.values().into_iter(),
        }
    }
}

fn main() {
    let v: Vec<_> = DiffStruct::V(vec![1,2,3]).to_iter().collect();
}

playground

So that I can minimize the collect behavior of my code for best performance, but it does not compile, any workaround to achieve this?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
Renkai
  • 1,991
  • 2
  • 13
  • 18
  • It's not 100% clear to me whether you want to iterate over references to the values, or copies, or what, but here's [an example of using `Either`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=755f061ae6583d6ebefba3695ed59ec0) as one of the answers to the other question suggests. – trent May 14 '20 at 15:50
  • And [here's an example using boxed trait objects](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=843f66715278d964dd59a3544d14086e), but iterating over references instead. (The choice of whether to iterate over references or values is independent of whether you use `Either` or `Box`; you can mix and match.) – trent May 14 '20 at 15:57

1 Answers1

2

Assuming you want to take ownership of DiffStruct and not just borrow it when you collect its values:

use std::collections::HashMap;

pub enum DiffStruct {
    V(Vec<i32>),
    M(HashMap<i32,i32>),
}

impl DiffStruct {
    fn to_iter(self) -> Box<dyn Iterator<Item = i32>> {
        match self {
            DiffStruct::V(vec) => Box::new(vec.into_iter()),
            DiffStruct::M(map) => Box::new(map.into_iter().map(|(_, v)| v)),
        }
    }
}

fn main() {
    let vec_values = vec![1, 2, 3];
    let mut map_values = HashMap::new();
    map_values.insert(1, 1);
    map_values.insert(2, 2);
    map_values.insert(3, 3);

    let ds_vec = DiffStruct::V(vec_values);
    let ds_map = DiffStruct::M(map_values);
    let collected_from_vec: Vec<_> = ds_vec.to_iter().collect();
    let collected_from_map: Vec<_> = ds_map.to_iter().collect();
}

playground

See also

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98