Vectors and Hashmaps of references and iterators with double references

I have a set of data structures over a set of static lookup data that I'm intentionally leaking using Box::leak(). Thus the type of the data structure is: HashMap<MyKeyType, &'static LookupData>

Iterating over this structure is a little awkward, because the iterator gives a &T, so code like this fails to compile:

let filtered_things: Vec<&'static LookupData> = mymap.values().filter(...).collect();

This fails with a message "a collection of type std::vec::Vec<&LookupData> cannot be built from std::iter::Iterator<Item=&&LookupData>"

I can solve this by hand by adding an extra .map(|data| data) which coerces the && into a single ref... but is there a better pattern or way of doing this?

You can use copied instead of a map to copy the underlying reference.

1 Like

Will .copied() produce an iterator over LookupData or &LookupData? I thought from the docs that it would call .copy() which would end up with a LookupData.

copied() will remove just one layer of reference.

1 Like

Each call to copied is guaranteed to remove exactly one layer of indirection. Remember that references are copy.

1 Like

Great, thank you! I still don't quite understand what the phrase "references are copy" means... is there a link in the Rust book that would help me understand that better?

Any type is considered copy if you can, well, copy it. The thing is that given a type T, there is another type called &T known as a reference to T. This &T reference type is always copy, because copying the reference to an object doesn't involve copying the object itself and is therefore a cheap copy operation.

Just out of curiosity, why are you leaking data?

I'm writing a web service with a bunch of static lookup tables that cross-reference eachother. So at service start (in main) I'm creating a set of hashmaps and structures that cross-reference eachother, all with static lifetime, and then they become immutable while the multithreaded server runs they can all access the immutable data. Static lifetime was the only way to get the cross references to work.

Could you use Arc for this?