One of the most common (if minor) frustrations I run into with Rust is refactoring iterator expressions. So for example, I might start with:
for item in vector {
println!("{}", item);
}
Later on, I decide I need to know the index too:
for (index, item) in vector.enumerate() {
println!("{}: {}", index, item);
}
... which of course does not compile, because enumerate is on Iterator and Iterator is not implemented for Vec.
So I was wondering if there was any technical or usability reason not to implement most of the Iterator methods on collections directly, and have them delegate through into_iter? With something like that, the refactoring above would be valid, and you wouldn't need to call the iter method.
That's because there's vector.into_iter(), vector.iter() and vector.iter_mut() which give you 3 flavors of enumerate().
Direct implementation would either have to choose one, or be split into enumerate_owned() + enumerate_ref() + enumerate_ref_mut().
Edit: actually, it could also be solved by having .enumerate() implemented separately on slices, so vector.enumerate() and (&vector).enumerate() would be different.
Yeah, I tried implementing this and I ended up having to write (&vector).enumerate() as you said. Which is pretty much just as inconvenient as changing &vector to vector.iter().
There isn't a fundemental reason this can't happen, though it would cause some (mostly minor) namespace conflicts. For example, Option<T> implements IntoIterator but also has its own map method.
For now, the itertools crate provides functions like enumerate that take a generic IntoIterator, so that you can write: