I was surprised that this swift code behaves nicely:
let values = ["Hello", "Test"]
var count = 0
for string: String in values {
    count = count + 1
    print("count is: ", count)
    print(string)
} 
with output of:
count is:  1
Hello
count is:  2
Test
but making the String into String? creates an infinite loop.
   let values = ["Hello", "Test"]
    var count = 0
    for string: String? in values {
        count = count + 1
        print("count is: ", count)
        print(string)
    }
with output of:
count is:  1
Optional("Hello")
count is:  2
Optional("Test")
count is:  3
nil
count is:  4
nil
count is:  5
nil
count is:  6
nil
count is:  7
nil
count is:  8
(ad infinitum)
Swift has been so good at catching weird code problems that I was surprised I could walk into such a mess without warning or error. Is this really what one would expect from Swift 4? And if so, why?
To understand this issue it helps to recollect how for-in loops work:
for s in values {
    print(s)
}
creates an iterator of the sequence, and calls the iterator's next() method until that returns nil:
var it = values.makeIterator()
while let s = it.next() {
    print(s)
}
Your second version is equivalent to
var it = values.makeIterator()
while let s: String? = it.next() {
    print(s)
}
and now the compiler warns:
warning: explicitly specified type 'String?' adds an additional level
of optional to the initializer, making the optional check always succeed
    while let s: String? = it.next() {
          ^      ~~~~~~~   ~~~~~~~~~
                 String
So what happens here is that the String? returned from it.next()
is wrapped into a “nested optional” .some(it.next()) of type String??, which is then optionally bound to s: String?.
This does always succeed, because .some(it.next()) is not String??.none.
Therefore the loop never terminates.
One could argue that the compiler should warn as well for
for s: String? in values {
    print(s)
}
                        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