0
impl Hash for MyType {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
    }
}

fn my_fn(...) -> (Vec<MyType>, HashMap<key_type, &MyType>{
    let mut my_vec: Vec<MyType> = ...construct vec...;
    let my_hmap: HashMap<key_type, &MyType> = my_vec.par_iter().map(|n| n.name.clone(), n).collect();

    (my_vec, my_hmap)

I get the following error:

fn my_fn(...) -> (Vec<MyType>, HashMap<key_type, &MyType>) {
                                                    ^ expected named lifetime parameter

What I think I understand is that the referenced variable exists only in the function's scope, since I can build the hmap just fine within the function without returning it. But I don't know a solution. Thank you.

AmanKP
  • 95
  • 8
  • Does this answer your question? [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – cafce25 May 20 '23 at 09:58
  • @cafce25 I have not yet studied lifetimes since I'm new so the answer below is more helpful to me. However if you feel that the answers are identical functionally please feel free to close my question. – AmanKP May 20 '23 at 13:27
  • 2
    Obviously a hand tailored solution is going to be more immediately useful to you, the Q/A linked contains some gems on why it doesn't work the way you'd want it to and how to work around it so I recommend you study it for your long time benefit. After all more than anything else the duplicate question feature here is just a convenient way to link multiple questions together. – cafce25 May 20 '23 at 13:36
  • Nitpick: `par_iter()` is unlikely to give you any perf benefit. – Chayim Friedman May 20 '23 at 20:03

1 Answers1

2

You cannot.

Rust's borrow checker prevents keeping references to the Vec because you move your vector when returning it from function.

One option is to use indexes instead of references:

fn my_fn(...) -> (Vec<MyType>, HashMap<key_type, usize>{
    let mut my_vec: Vec<MyType> = ...construct vec...;
    let my_hmap: HashMap<key_type, usize> = my_vec.par_iter()
           .enumerate()
           .map(|(i, n)| (n.name.clone(), i))
           .collect();

    (my_vec, my_hmap)
}

Another option is to use Rc (or Arc in case of using multiple threads) but it would have worse memory access patterns:

fn my_fn(...) -> (Vec<Rc<MyType>>, HashMap<key_type, Rc<MyType>>{
    let mut my_vec: Vec<Rc<MyType>> = ...construct vec...;
    let my_hmap: HashMap<key_type, usize> = my_vec.iter()
           .map(Rc::clone)
           .map(|n| (n.name.clone(), n))
           .collect();

    (my_vec, my_hmap)
}