Assume I have some function do_stuff
that takes a &HashSet<X>
and wants to collect the items into a Vec<X>
by copying all the elements. What is the canonical way to do that? I have basically found the following ways to do this:
Using _.clone().into_iter().collect()
(GodBolt Link):
use std::collections::HashSet;
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
struct X {}
struct Y {
xs: HashSet<X>,
}
fn do_stuff(y: &Y) -> Vec<X> {
y.xs.clone().into_iter().collect()
}
This is recommended here:
Using _.iter().cloned().collect()
(GodBolt Link):
use std::collections::HashSet;
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
struct X {}
struct Y {
xs: HashSet<X>,
}
fn do_stuff(y: &Y) -> Vec<X> {
y.xs.iter().cloned().collect()
}
This is recommended here:
Using Vec::from_iter(_.iter().cloned())
(GodBolt Link):
use std::collections::HashSet;
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
struct X {}
struct Y {
xs: HashSet<X>,
}
fn do_stuff(y: &Y) -> Vec<X> {
Vec::from_iter(y.xs.iter().cloned())
}
This is recommended here:
I have two questions:
What is the essential difference between the above methods?
What is the canonical way to collect the items from a &HashSet<X>
into a Vec<X>
?
Related:
_.clone().into_iter().collect()
This one creates an intermediate copy of HashSet
. Which is not something you want, its an unneeded allocation and processing. The rule of thumb is: prefer .cloned()
over .clone()
.
These two:
_.iter().cloned().collect()
Vec::from_iter(_.iter().cloned())
are equivalent. The first one is more readable IMO.