Definition of trait Iterator

trait Iterator is defined as:

pub trait Iterator {
    type Item;

Is there a reason why it is not defined as Iterator<T> , or is this mostly a historical / backward compatibility matter ?

1 Like

It used to be that way, but RFC 195 introduced associated items with the idea that they should be used for outputs, especially when there's only one real possibility.

2 Likes

Well, the question is the opposite: why should it be Iterator<T>?

The general idea behind Iterator<T> versus Iterator<Item=T> is that the first one lets the caller choose what they iterate over (kinda like generics in argument position - e.g. fn (impl Foo)), while the second version lets the iterator dictate the item type (e.g. fn() -> impl Foo).

Semantically, I think it would be quite weird if the type system let you implement Iterator multiple times for the same type... Imagine I implemented Iterator<Key> and Iterator<Value> for a cursor over some hypothetical map type, does that mean the iterator would have to maintain bookkeeping for both the key iterator and the value iterator at the same time? What if I don't care about the values? Also, does that require you to consume it in a particular way (each <_ as Iterator<Key>>::next() must be followed by a <_ as Iterator<Value>>::next() call or once you've started iterating over keys any attempt to get the next value will trigger a panic, etc.)?

7 Likes

Plus, if that map is generic, Key and Value could be the same type!

3 Likes

For Iterator<T> to implement IntoIterator [1], the latter would have to be parameterized too, and I don't think for could handle every ambiguity that would introduce.

In practice, when generics are needed, they go on the iterator type (e.g. std::slice::Iter<'a, T>).


  1. and other reasons ↩ī¸Ž

1 Like

And, importantly, for x in y { dbg!(x); } only works because there's no generic parameter on Iterator. If there could be multiple iterator implementations, there's no reasonable way for for loops to pick which to use -- even if the y is already an iterator.

1 Like