Вы не можете позвонить next
, потому что next
- это mutating
. next
изменяет состояние итератора , так что он "приближается" к концу.
for
l oop не вызывает next
напрямую. Он создает изменчивую копию c
(var
) и вызывает next
для этого:
// The for loop basically does this:
var copy = c // creates a copy
var element = copy.next()
element = copy.next()
element = copy.next()
...
Причина, по которой вторая для l oop начинается с начало именно из-за этого. for
Циклы на самом деле не меняют состояние того, что вы перебираете. Они создают копию, работают с копией, а затем выбрасывают ее.
Один из способов избежать такого поведения копирования - сделать Countdown
классом:
class Countdown: Sequence, IteratorProtocol {
// internal state
var count: Int
// IteratorProtocol requirement
func next() -> Int? {
if count == 0 { return nil } else {
defer { count -= 1 }
return count
}
}
init(from n: Int){
count = n
}
}