Evaluating the following code, I would expect a single printing of Hello World
. Instead, it causes an infinite loop. Can someone explain why?
let array = ["what"] for text: String? in array { print("Hello World") }
(Removing the optional ?
obviously makes it print only once)
This means that the loop will run forever ( infinite loop ). To stop this, we can use break and we have used it. if a == "n" -> break : If a user enters n ( n for no ), then the loop will stop there. Any other statement of the loop will not be further executed.
Fast enumeration is a language feature that allows you to efficiently and safely enumerate over the contents of a collection using a concise syntax.
This is an unexpected result, but it is happening because of the way Swift for in
loops work under the hood.
for in
takes a variable and a Sequence
. Swift calls makeIterator()
on the Sequence
to get an IteratorProtocol
which returns successive items when next()
is called on the iterator. next()
returns an Optional so that it can return nil
when all of the items have been exhausted.
In a normal case, you receive the non-optional values and Swift continues giving them out until nil
is received in which case the loop ends.
This is the equivalent of your code when you don't use an optional:
let array = ["what"] var iter = array.makeIterator() while let text = iter.next() { print("Hello World") }
The optional binding (while let
) fails when iter.next()
returns nil
and the loop ends.
In your case, you have said that you will explicitly receive nil
values (by declaring your loop variable as an optional), so when next()
is called on the iterator and it is out of values, it hands you a nil
which you graciously receive and the loop continues. The iterator continues to hand out nil
and you continue to take them, and you have an infinite loop.
This is the equivalent of your code when you use an optional:
let array = ["what"] var iter = array.makeIterator() while let text: String? = iter.next() { print("Hello World") }
In this case, the optional binding always works because text
can receive the nil
.
This blog gives a nice detailed explanation of what is happening under the hood with Swift for in
loops.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With