`from_iter()` vs `collect()`

I sometimes like to call FromIterator's from_iter() (like Vec::from_iter() or HashMap::from_iter()) directly, particularly when the compiler cannot infer the return type for collect(), and even more particularly when that return type is using some type arguments that the compiler could infer.

However, recently clippy started warning about using from_iter() directly. This made me wonder if people mostly prefer using collect() even if turbofishing is required, or if others also like to use from_iter() directly for this purpose. I feel like this change makes the code slightly worse:

-    let etlds = HashMap::from_iter(
-        data.etld_index
-            .iter()
-            .map(|(idx, etld)| (*etld, idx.clone())),
-    );
+    let etlds = data
+        .etld_index
+        .iter()
+        .map(|(idx, etld)| (*etld, idx.clone()))
+        .collect::<HashMap<_, _>>();
Using FromIterator
  • HashMap::from_iter(iter)
  • iter.collect::<HashMap<_, _>>()
  • let foo: HashMap<_, _> = iter.collect::<HashMap<_, _>>()

0 voters

(For the third option, the turbofishing should not be there -- can't edit the poll anymore, sorry!)

Would like to hear your opinions!

1 Like

Or a third option,

    let etlds: HashMap<_, _> = data
        .etld_index
        .iter()
        .map(|(idx, etld)| (*etld, idx.clone()))
        .collect();
3 Likes

Fair point! Added your third option.

There's no turbofish required in scottmcm's suggestion, so I'm not sure which of the options is supposed to represent it? (Did you copy and paste and forget to delete that part?)

Yes, exactly. Can't change the poll anymore, but added a note to hopefully make this slightly clearer.

1 Like

I don't like wrapping long iterator chains in from_iter, like in your example. But if I already have the iterator in a local or it's a short expression, then from_iter is nice -- especially if I can use an implicit IntoIterator.

let refs1 = Vec::from_iter(&collection);
let refs2 = collection.iter().collect::<Vec<_>>();
let refs3: Vec<_> = collection.iter().collect();

I do use collect in both forms for longer iterators, usually with type annotation if I am binding to a local, or turbofish otherwise.

6 Likes

I, too, prefer from_iter() sometimes. I think if your professional opinion/taste justifies using it, do feel free to ignore / #[allow] the lint.

3 Likes

I proposed adding FromIterator to the prelude to make the from_iter form more convenient. This has been discussed as part of a possible new prelude for the 2021 edition.

8 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.