I noticed that the HashSet set operations return operation-specific types; .difference() returns a Difference, etc. The operation result types implement Iterator; the idea presumably being "We don't know what you want to stick the result into -- here's an Iterator so you can stick the result wherever you need it.", which is really neat!
However if you simply .collect() the results you'll get node of references:
let mut s1 = HashSet::new();
s1.insert("hello".to_owned());
let mut s2 = HashSet::new();
s2.insert("hello".to_owned());
s2.insert("world".to_owned());
let isect = s1.intersection(&s2);
let res: HashSet<_> = isect.collect();
// res == s1 ???
At this point s1 and s2 will be HashSet<String>, while res will be HashSet<&String>. I presume this is to avoid unnecessary clones -- but I'm in a situation where I need to create an intersection of two sets, then check if the result is identical to s1. This causes a problem because of the type difference.
I solved this by:
let res: HashSet<_> = isect.map(|x| x.to_string()).collect();
.. but I have a distinct feeling that there's a better way to to it.
Is there a "nice and clean" way to do this without having to allocating the res strings?