Tracking Issue for Iterator::try_collect
· Issue #94047 · rust-lang/rust (original) (raw)
Feature gate: #![feature(iterator_try_collect)]
This is a tracking issue for adding the try_collect()
method to the Iterator
trait, as originally discussed here. Iterator::try_collect()
is a fallible variation of Iterator::collect()
analogous to similar methods for reduce
and fold
, among others, that provides a simpler, generic way to collect iterators of Try
elements into Try
-wrapped types.
Difference from Iterator::collect
In terms of functionality, the main difference between try_collect()
and collect()
is that try_collect()
allows you to fallibly collect iterators yielding types that implement Try
but not FromIterator
, which collect()
can't do. Concretely this means you can try_collect()
iterators yielding ControlFlow<_, i32>
into ControlFlow<_, Vec<i32>>
, which you can't do with collect()
.
It's also a &mut self
method instead of collect
's self
, so that you can resume iteration after it early exits on an error. (Like how try_fold
is &mut self
while fold
is just self
.)
Another benefit of try_collect()
is discoverability. Because the discoverability of the "collect-into-Result
" appears to be lower than desired, "promoting" the technique into its own method seems like a good way to increase its discoverability and reach more users who would find it useful. (One of many examples of people just not being able to find the Option: FromIterator
themselves: https://users.rust-lang.org/t/try-collect-as-iter-consuming-operation/20479?u=scottmcm.)
Finally, try_collect()
presents a small ergonomics benefit in terms of type hints when collecting, namely that you only have to hint at the output type you're collecting into, not the whole Try
type. For example, that means you can collect an iterator yielding Result<i32, SomeComplicatedError>
with try_collect::<Vec<_>>()
, as opposed to having to specify the whole Result
with collect::<Result<Vec<_>, _>>()
.
Public API
trait Iterator { type Item;
fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
where
Self: Sized,
<Self as Iterator>::Item: Try,
<<Self as Iterator>::Item as Try>::Residual: Residual<B>,
B: FromIterator<<Self::Item as Try>::Output>;
}
Steps / History
- Implementation: Add a try_collect() helper method to Iterator #94041
- Final comment period (FCP)
- Stabilization PR
Unresolved Questions
- Should it have a more complicated signature to be able to return the partial results too? (@CAD97 https://internals.rust-lang.org/t/idea-fallible-iterator-mapping-with-try-map/15715/6?u=scottmcm )
- Should it take
self
rather than&mut self
, to prevent users from accidentally continuing to use the iterator after atry_collect()
failure? Note that you can still continue to use the iterator if you useby_ref()
first, so it's not necessarily a functionality change. - Does the name
try_collect()
conflict too much with the idea of collecting that's fallible in allocation? (i.e. collecting withVec::try_reserve
or similar)