From my forum question:
Consider an iterator that does two things:
- Read data from a data source.
- Perform a complex calculation on the data read.
This means that next is computationally expensive, but skip could be cheap if
implemented by hand. It could just do step 1 and throw the data away without doing
step 2.I have tried various ways to do this [... but] I cannot find a public API to create a Skip
except by calling Iterator::skip. Is this impossible?
It's easy, according to @scottmcm: implement my own Iterator::nth method, and I will get a skip implementation for free.
In retrospect it makes sense, but it was not obvious to me at all just from reading the docs. It is not mentioned in the Implementing Iterators section of the API, or the docs for either method. And as the link in my post suggests, trying to work my way around the ownership of the APIs led me quite far afield.
Admittedly it's not the most common case, but I think it would save others time if the standard library at least mentioned this somewhere.
EDIT: fixed forum link which changed its name when I marked it solved.
A section about "you should consider overloading these things" definitely sounds good. fold should also be on that list. (In the future or in nightly try_fold is in that list too, as its docs mention.)
Your forum link is broken.
The docs do say
Iterator's full definition includes a number of other methods as well, but they are default methods, built on top of next, and so you get them for free.
However, I do like @scottmcm 's suggestion, about talking about which methods you may want to override.
Such hints should be non-normative though to allow the implementations, especially specializations, to use different approaches in the future.
Agreed, @the8472. I was picturing more which methods to consider overloading, not specifically which things use them. (Or, contrapositively, which things there's usually no reason to overload, like for_each, because the default implementation is generally as good as it gets because it's a trivial wrapper.)
So basically this issue is about adding some documentation on which methods you might want to override right? Which methods do you think are best to mention? Or did I misinterpret the discussion?
@DevQps That's correctly, probably under or near https://doc.rust-lang.org/nightly/std/iter/index.html#implementing-iterator. For now my inclination would be to mention nth and fold -- once stable it should be try_fold instead, but IIRC we don't mention unstable in the broader docs until it stabilizes.
What about adding this line of text at the end of the "Implementing Iterator" section?
Also note that
Iteratorprovides a default implementation of methods such asnthandfold
which callnextinternally. However, it is also possible to write a custom implementation of
methods such asnthandfoldif an iterator is able to compute them more efficiently without calling
next.
Feel free to adjust the text or make something up yourself :) If you agree I will create a PR for this.
I think it would also be nice to add something to the skip documentation. How about this?
Rather than overriding this method directly, instead override the
nthmethod.
@DevQps, in case it wasn't clear or you are not watching your GitHub notifications, I approve of both your and @czipperz's suggestions. I look forward to the PR!
@jhwgh1968 Sorry for the late reply! I apparently don't get notifications for thumbs ups and the like! I will hopefully be able to create a PR somewhere this midday.
Most helpful comment
What about adding this line of text at the end of the "Implementing Iterator" section?
Feel free to adjust the text or make something up yourself :) If you agree I will create a PR for this.