How, exactly, will it work? repeat_with
creates an iterator by repeatedly calling a FnMut
closure or function that returns a value every time. Please answer with code here, since if it can't call clone()
, nor can it rely on the item being Copy
, it has no way to get the same item that it just got from next()
ever again.
Remember that, by definition, next()
returns an item and removes it from the underlying iterator. That item cannot be obtained from the underlying iterator ever again, since it's been removed; to implement your step_by(0)
behaviour, StepBy
needs to somehow repeat that item.
That's an error from Vec
- it's telling you that you've tried to collect more items than it can fit in memory. It's useful to have an infinite iterator without take()
in other circumstances, though - for example, if I'm using a loop with break
to process the items from the iterator, or if I'm applying a short-circuiting iterator method (like find
) where I know that it will eventually find the item.
Also note that Rust does not have the concept of infinite iterators per-se at the moment. It knows about exact length iterators via the ExactSizeIterator
trait, and about indefinite iterators in general, where the iterator's size is not known, but you'll know if it's run out of items, but not iterators that will never run out. Anything that requires Rust to reason about infinite iteration will require this to be fixed first.
This is definitely an issue, and I'd make a bug report against Rust for this, because it'd be nice to have the error reporting look deeper and tell you that std::iter::Take<RangeFrom<{integer}>>: ExactSizeIterator
would be satisfied if RangeFrom<{integer}>
implemented ExactSizeIterator
.
I would note that if I remove the step_by(2)
, I do get an error message telling me why Take
does not implement ExactSizeIterator
here, so the compiler has the knowledge it needs to give you a good error message, it's just that it's not using it (possibly because there's a risk of it taking a really long time to generate the error message):
error[E0599]: the method `len` exists for struct `Take<RangeFrom<{integer}>>`, but its trait bounds were not satisfied
--> src/main.rs:5:33
|
5 | println!("{}",(0..).take(2).len());
| ^^^ method cannot be called on `Take<RangeFrom<{integer}>>` due to unsatisfied trait bounds
|
::: /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/range.rs:189:1
|
189 | pub struct RangeFrom<Idx> {
| ------------------------- doesn't satisfy `RangeFrom<{integer}>: ExactSizeIterator`
|
::: /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/take.rs:19:1
|
19 | pub struct Take<I> {
| ------------------ doesn't satisfy `_: ExactSizeIterator`
|
= note: the following trait bounds were not satisfied:
`RangeFrom<{integer}>: ExactSizeIterator`
which is required by `std::iter::Take<RangeFrom<{integer}>>: ExactSizeIterator`