-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Description
Feature gate: #![feature(iter_collect_into)]
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.
Public API
trait Iterator {
type Item;
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
where
Self: Sized;
}
Steps / History
- To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Unresolved Questions
- 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.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Corfucinas, aleksuss, kkocdko, stuhood, MatrixDev and 26 more
Metadata
Metadata
Assignees
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
Corfucinas commentedon May 31, 2022
This would be a useful method when using
MPSC
and 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_into
feature, then I would like us to discuss these issues here and now beforecollect_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 thecollect_into
feature should (or shouldn't) have in order to facilitate such atry_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 (returnfalse
and just leave the remainder unread/uncollected in the iterator? panic?).You can currently mock this yourself by implementing
Extend<A>
(though theExtend
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...)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_into
is implemented calling Extend::extend).frengor commentedon Jan 18, 2023
Yeah, I think it should be. However, seeing that
try_collect
doesn't handle fallible allocations, the name of eithertry_collect_into
ortry_collect
should 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 aTryExtend
trait (it would be good to add aTryFromIterator
trait, too), but maybe there is a better way to handle fallible allocations (?).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
usesExtend
for this exact reason.Iterator::collect_into<E: Extend>(e: E)
? #45840theemathas commentedon Jul 6, 2025
Is it reasonable to add another method that takes and returns an
E
instead 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_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 theExtend
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?