Minor but important point, you’re not looking at the range, you’re looking at its indices eachindex, which in this case is a Base.OneTo(5). But if you remove that method call, this discrepancy remains.
The main point here is that state is not an iteration count or the corresponding item. See how the first two items below (1,2) are the same for the range and the array, but the states are different? Although states indicate iteration progress, there’s no expectation we can intuit the state that produces the n-th iteration. The state can actually be anything, even strings*.
struct HelloWorld end
function Base.iterate(::HelloWorld, state=nothing)
if state == "ZA"
("WORLD!", "STOP TIME")
elseif state == "STOP TIME" # no more items
nothing
else # unexpected or no states start at Hello
("Hello ", "ZA")
end
end
for i in HelloWorld() println(i) end # Hello WORLD!
println(iterate(HelloWorld(), "whoops")) # ("Hello ", "ZA")
println(iterate(HelloWorld(), "ZA")) # ("WORLD!", "STOP TIME")
println(iterate(HelloWorld(), "STOP TIME")) # nothing
As stated above, Iterators.rest takes a state as its second argument, which is usually an implementation detail of the iterator. It so happens that state=1 does not refer to the same iteration point for a range and a vector. Iterators.rest should mostly be used on the iterators that you define, since the iteration state is otherwise not usually part of any API.
If you are curious and want to look at the definition of iterate for ranges and for vectors, you can type @edit iterate(1:5) and @edit iterate([3, 5, 6]) in your REPL and look at the code. The full iteration protocol is detailed in the docs here and there.
In contrast, the user-facing Iterators.drop does not rely on the internals of the iteration protocol and can be used to skip the n first elements, as you would expect. With your examples, when dropping 1 element (i.e. starting at the second element of the iterator):
Thank you both so much for clarifying that distinction in such a clear and understandable way. I don’t think I would have pick up on it otherwise. I just marked the first answer as there is currently no way to mark multiple solutions.