Why does a let variable work in for ... in but not while let ... ?

I was trying out the use of Sequence and IteratorProtocol. But something here surprised me. There is no error on the for statement but the while statement has the error "Cannot use mutating member on immutable value: 'threeToGo' is a 'let' constant".

This looks like an inconsistency in Swift. They are both mutating the threeToGo variable. Can anyone give an explanation?

func even(_ i: Int) -> Bool { i % 2 == 0 }

struct Countdown: Sequence, IteratorProtocol {
    var count: Int
        
    mutating func next() -> Int? {
        if count == 0 {
            return nil
        } else {
            defer { count -= 1 }
            return count
        }
    }
}

let threeToGo = Countdown(count: 3)
while let i = threeToGo.next() {
    print(i)
    if even(i) { break }
}
print("We broke out")
for i in threeToGo {
    print(i)
}

Where does the for loop mutate threeToGo?

The for loop does not mutate threeToGo. It goes through each element in the sequence and prints the element.

The while loop generates a syntax error because you made the next function mutating. threeToGo is a let constant so you can't change it or call a mutating function on it.

What @szymczyk explained, plus:

It is not a while vs for question.

Just try:

let newValue = threeToGo.next()

You will get the same error.

Why does a let variable work in for ... in but not while let ... ?
 
 
Q