Accept an Iterator which can be count without consuming itself

I have a function which takes an iterator as input, and I want to know how many elements in it:

fn foo<I: IntoIterator<Item=usize>>(iter: I) {
    let count = iter.into_iter().count();
}

But this will consume the iterator, and it is reasonable because some iterator like link list may not be counted without consuming itself.

But in my case, I do want to know the count before iterate it, so I want to take some iterator type which can be count without consuming itself, but I didn't find a trait like this.

So do I miss something or is there any workaround?

ExactSizeIterator means "an iterator that knows how long it is without actually iterating". But you if you don't want that, you can always just accept an iterator that is Clone and yields references; this will almost exclusively restrict the generic type parameter to borrowing iterators, which you can then safely consume.

2 Likes

There's also Iterator::size_hint which has a bunch of caveats on it, but could be useful for things like preallocating where you don't need to be super precise about the count.

1 Like

I guess this is how collect() pre-allocate memories?

It's a bit hard to find the actual implementation because they use specialisation to make cases like some_vec.into_iter().collect() faster, but that's what it looks like.

1 Like

One probably shouldn't, since most of the iterators are not Copy (and for the good reason, AFAIK).

1 Like

Right, I meant Clone. I was already thinking ahead to saying that references are Copy. :sweat_smile: