Needing to call collect with a super fish[0], like so:
let x = iterator.collect::<Vec<String>>();
Or with a type hint:
let x: Vec<String> = iterator.collect();
feels like an unnecessary paper cut. It's merely annoying if you know how to write a super fish or correct type hint, but I think for a new rust programmer it might be more than annoying.
If so, then maybe it would be a good idea to provide easy-to-use functions which allow collecting into vecs, sets, and maps:
trait IntoVec<T>: Sized {
fn into_vec(self) -> Vec<T>;
}
trait IntoSet<T>: Sized {
fn into_set(self) -> BTreeSet<T>;
}
trait IntoMap<K, V>: Sized {
fn into_map(self) -> BTreeMap<K, V>;
}
// blanket implementations can be provided for
// iterators, for example:
impl<T, I: Iterator<Item = T>> IntoVec<T> for I {
fn into_vec(self) -> Vec<T> {
self.collect()
}
}
I think that since this is a very common case, it will save a lot of typing and compile time errors, and be a usability win for new rust programmers. They'll need to learn about super fish and type hints eventually, but by making it unlikely to be an early stumbling block, we can help lower the slope of the learning curve.
The choice of BTreeSet
and BTreeMap
instead of HashSet
and HashMap
is intentional. If a user needs an ordered map, using a hash map will produce an incorrect program. If a user doesn't need an ordered map, then using an ordered map will merely produce a slower-than-necessary program. Also, using ordered maps and sets have deterministic and implementation-independent iteration order, which can be useful by making bugs appear consistently, and program behavior not changing from run to run.
If it's worth it, we could also expose collecting into HashSet
s and HashMaps
as into_unordered_X
, or into_hash_X
.
What do y'all think? Is this worth an RFC?
[0] ::<> (not sure if this is actually called a super fish but I'm rolling with it anyways)