Repository navigation
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-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Description
Feature gate: #![feature(peekable_iterator)]
This is a tracking issue for the PeekableIterator trait, which extends Iterator with peek_with and related methods that inspect the next element without consuming it.
Public API
// core::iter
pub trait PeekableIterator: Iterator {
// required method
fn peek_with<T>(&mut self, func: impl for<'a> FnOnce(Option<&'a Self::Item>) -> T) -> T;
// provided methods
fn peek_map<T>(&mut self, func: impl for<'a> FnOnce(&'a Self::Item) -> T) -> Option<T>;
fn next_if(&mut self, func: impl FnOnce(&Self::Item) -> bool) -> Option<Self::Item>;
fn next_if_eq<T>(&mut self, expected: &T) -> Option<Self::Item>
where
Self::Item: PartialEq<T>,
T: ?Sized;
}Steps / History
- ACP:
Peektrait for peekable iterators libs-team#176 - Implementation:
- Take 1: Add
PeekableIteratortrait #132976 - Take 2: Add
PeekableIteratortrait #144935
- Take 1: Add
- Final comment period (FCP)1
- Stabilization PR
Unresolved Questions
- Should
peektake&mut selfor&self?&selfmakes sense for iterators such ascore::slice::iterbut precludes implementing the trait onPeekable. What about the return type ofResolved by having the method take a callback.peek? We could always make it returnSelf::Itemlike itertools’sPeekingNext, but that would prevent this trait from being implemented for consuming iterators such asvec::IntoIter, as well asPeekableitself.If we use an associated type, then what should be the bound for it:Borrow,AsRef, or something else?
Footnotes
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-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Activity
YkdWaWEzVmphR1Z1 commentedon Jan 3, 2025
Wouldn't it be a lot more general for the item to be an iterator. Peek could be implemented in terms of <Self::PeekedItem as PeekedIterator>::peek_iter.next(). Peekable stores an Option, so it would just return an Option Iterator. But a slice for example could return slice::Iter. I also wonder what benefit this brings over methods on the iterator types. The example uses the Chars iterator, but it also as an as_str() method. The same applies for slice and the range types. So the trait would only be useful in generic code and for that it had to be a lot more general than it currently is.
This design is the Peekable struct as trait. The Peekable struct has been designed this way, because it has to work with any iterator. But many iterators can just return cheaply a new iterator without changing the old iterator. This applies probably to any iterator which does not store a closure and whose internal iterator does not have side effects.
bluebear94 commentedon Apr 16, 2025
This still leaves the problem of what type of element the returned iterator yields. For
Peekable<impl Iterator<Item=T>>andslice::Iter<T>, this should be&T, but forRange<T>, the iterator would have to be overT.theemathas commentedon Aug 5, 2025
Maybe the correct function signature is this?
This would mean, for example, that
str::Charswould be able to implement this without having a field inside the iterator that contains achar. Instead, it would be able to create a local variable in thepeekmethod that stores thechar.wmstack commentedon Aug 5, 2025
I like this method signature, although I think the parameter with an
Optionis a little difficult to work with inside a closure.next_ifsignature callback takesfunc: impl FnOnce(&Self::Item) -> bool), so it might be more convenient to move theOptionoutside. Alternatively, a little helperpeek_mapcan be added that does that.