You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a tracking issue for adding the collect_into method to the Iterator trait. Iterator::collect_into lets an iterator to be collected into a collection which implements the Extend trait, consuming the iterator and adding every of its item to the collection.
Adding this method has also the benefit of making the Extend trait more discoverable.
Not sure if this is where any discussion should go but I would like it to formally request from now that consideration should be given to the ability to (try to?) collect into a fixed-size buffer well, primarily for purposes of avoiding heap allocation. Presumably this would just be a separate feature (try_collect_into?) but if the design of that feature would in any way conflict with the current collect_into feature, then I would like us to discuss these issues here and now before collect_into stabilizes any further.
collect_into is nice because it lets you reduce allocations by directly extending a previous buffer/collection rather than allocating into a wholly separate one and then forcing you to merge the two, which (boilerplate aside) might be less efficient. On the other hand, collecting into a fixed-size buffer could let you use iterators to directly collect into a stack-allocated array/slice, which is pretty much guaranteed to be a huge performance win. I am happy to open a separate issue to specifically track such a feature, but again, I just wanted to mention it here so that if there's something the collect_into feature should (or shouldn't) have in order to facilitate such a try_collect_into in the future, we can hopefully fix it.
The idea is that sometimes you want to use the iterator façade to simplify code transforming an existing collection and your input set is either of a known size or a capped size. Being able to collect into a stack-allocated array or mutable slice thereof would allow collecting the results of an enumeration cleanly. The semantics can (but don't necessarily have to) differ from those of collect_into, as certain things (like tracking the number of elements collected) become harder and there's the question of what to do when the provided fixed-length destination doesn't fit everything (return false and just leave the remainder unread/uncollected in the iterator? panic?).
You can currently mock this yourself by implementing Extend<A> (though the Extend api assumes infallibility) and then using .inspect() before .collect_into() to track the number of elements actually written to the collection.
EDIT:
It may very well just make more sense to loop over the items and add them to the array rather than building a huge façade around that. (Technically the same goes for collect_into as well...)
Is it worth it to have this API? The Iterator interface is already pretty large, and use cases can easily be written differently without this API.
I have an example use case, and would like to know how it should be written differently without this API:
I'm implementing a limited size priority queue (i.e. I want to keep only the top N elements of the queue at any given time).
For this I create a struct which has a collection and a size as its members.
I create this struct with a given size field - which is why it has to be created before it is being collected to.
Using this queue after implementing its insert fn, and extend fn is trivial when this API exists:
q = SizedQueue::new(5);
<some iter over large data>.collect_into(q);
Presumably this would just be a separate feature (try_collect_into?)
Yeah, I think it should be. However, seeing that try_collect doesn't handle fallible allocations, the name of either try_collect_into or try_collect should be changed to maintain coherence (also see the unresolved questions of try_collect).
but if the design of that feature would in any way conflict with the current collect_into feature, then I would like us to discuss these issues here and now before collect_into stabilizes any further.
I don't think it will really impact collect_into, I suppose it would mostly require adding something like a TryExtend trait (it would be good to add a TryFromIterator trait, too), but maybe there is a better way to handle fallible allocations (?).
It may very well just make more sense to loop over the items and add them to the array rather than building a huge façade around that. (Technically the same goes for collect_into as well...)
That would probably just be the implementation of TryExtend for slices I think, and having it implemented once in the stdlib doesn't require users to duplicate the same code over and over. collect_into uses Extend for this exact reason.
This would be convenient for doing stuff like .collect_into_owned(Vec::with_capacity(n)) or .collect_into_owned(HashMap::with_hasher(hash_builder)).
In an ideal world, this collect_into_owned method would also be able to accept a &mut Collection argument (in which case we wouldn't need the &mut E version of the method). However, for whatever reason, there's no blanket impl for the Extend trait on &mut _. Adding this blanket impl now would be a breaking change, since &mut is a fundamental type.
For reference, here's a cursory search for code on github that would break if we add the blanket impl.
Is it possible to do anything better about this?
Reacted by Wu Xiaoyun, teor, Alexander, Peter Lyons Kehl and Elichai Turkel
Activity
Corfucinas commentedon May 31, 2022
This would be a useful method when using
MPSCand appending to different vectors depending on the object.mqudsi commentedon Nov 8, 2022
Not sure if this is where any discussion should go but I would like it to formally request from now that consideration should be given to the ability to (try to?) collect into a fixed-size buffer well, primarily for purposes of avoiding heap allocation. Presumably this would just be a separate feature (
try_collect_into?) but if the design of that feature would in any way conflict with the currentcollect_intofeature, then I would like us to discuss these issues here and now beforecollect_intostabilizes any further.collect_intois nice because it lets you reduce allocations by directly extending a previous buffer/collection rather than allocating into a wholly separate one and then forcing you to merge the two, which (boilerplate aside) might be less efficient. On the other hand, collecting into a fixed-size buffer could let you use iterators to directly collect into a stack-allocated array/slice, which is pretty much guaranteed to be a huge performance win. I am happy to open a separate issue to specifically track such a feature, but again, I just wanted to mention it here so that if there's something thecollect_intofeature should (or shouldn't) have in order to facilitate such atry_collect_intoin the future, we can hopefully fix it.The idea is that sometimes you want to use the iterator façade to simplify code transforming an existing collection and your input set is either of a known size or a capped size. Being able to collect into a stack-allocated array or mutable slice thereof would allow collecting the results of an enumeration cleanly. The semantics can (but don't necessarily have to) differ from those of
collect_into, as certain things (like tracking the number of elements collected) become harder and there's the question of what to do when the provided fixed-length destination doesn't fit everything (returnfalseand just leave the remainder unread/uncollected in the iterator? panic?).You can currently mock this yourself by implementing
Extend<A>(though theExtendapi assumes infallibility) and then using.inspect()before.collect_into()to track the number of elements actually written to the collection.EDIT:
It may very well just make more sense to loop over the items and add them to the array rather than building a huge façade around that. (Technically the same goes for
collect_intoas well...)feature-engineer commentedon Jan 18, 2023
Regarding the last point:
I have an example use case, and would like to know how it should be written differently without this API:
I'm implementing a limited size priority queue (i.e. I want to keep only the top N elements of the queue at any given time).
For this I create a struct which has a collection and a size as its members.
I create this struct with a given size field - which is why it has to be created before it is being collected to.
Using this queue after implementing its insert fn, and extend fn is trivial when this API exists:
How would it look with an alternative API?
frengor commentedon Jan 18, 2023
The two codes are equivalent (in fact,
collect_intois implemented calling Extend::extend).frengor commentedon Jan 18, 2023
Yeah, I think it should be. However, seeing that
try_collectdoesn't handle fallible allocations, the name of eithertry_collect_intoortry_collectshould be changed to maintain coherence (also see the unresolved questions of try_collect).I don't think it will really impact
collect_into, I suppose it would mostly require adding something like aTryExtendtrait (it would be good to add aTryFromIteratortrait, too), but maybe there is a better way to handle fallible allocations (?).That would probably just be the implementation of
TryExtendfor slices I think, and having it implemented once in the stdlib doesn't require users to duplicate the same code over and over.collect_intousesExtendfor this exact reason.theemathas commentedon Jul 6, 2025
Is it reasonable to add another method that takes and returns an
Einstead of a&mut E? That is:This would be convenient for doing stuff like
.collect_into_owned(Vec::with_capacity(n))or.collect_into_owned(HashMap::with_hasher(hash_builder)).In an ideal world, this
collect_into_ownedmethod would also be able to accept a&mut Collectionargument (in which case we wouldn't need the&mut Eversion of the method). However, for whatever reason, there's no blanket impl for theExtendtrait on&mut _. Adding this blanket impl now would be a breaking change, since&mutis a fundamental type.For reference, here's a cursory search for code on github that would break if we add the blanket impl.
Is it possible to do anything better about this?