Code like the following is very common in Rust, especially (but not only) in documentation and examples. This exact line occurs four times in the std::collections::HashMap docs and tests, and similar lines are used throughout the example code for other collections and iterators:
let map: HashMap<_, _> = vec.into_iter().collect();
When the FromIterator trait is in scope (and default type parameter fallback is enabled), this could be written:
let map = HashMap::from_iter(vec);
This is shorter and has less extraneous noise, making it easier to write and to read. It is especially good in tutorials and other documentation for beginners because it avoids things like the turbofish operator or the
_ placeholder that require additional explanation. The main advantages are:
- It looks like other constructors, with the type name preceding the function name, and thus requires no type annotations.
collectcan be called only on an
IntoIterator. This means explicit
.iter()calls can be eliminated in some cases.
collect may still be more readable when it appears at the end of a chain of other iterator methods and/or its return type is inferred.)
Of course you can import FromIterator explicitly, but in small examples and tutorials, this cancels out any length benefit. In larger programs, adding an import is not a problem but I believe
collect is still generally used instead of
from_iter—not because it is always better, but because it’s lower-friction (due to the prelude) and better-known (due to the bias against
from_iter in docs and tutorials). The FromIterator docs even state:
from_iter()is rarely called explicitly, and is instead used through Iterator’s
- Expands the prelude without adding any functionality, only an alternate way to do something you can already do.
- Related: if both
from_iterbecome commonly used, it’s one more thing to learn (compared to a world where
from_iteris almost never used).