Чтобы понять эту проблему, полезно вспомнить, как работают циклы for-in:
for s in values {
print(s)
}
создает итератор последовательности и вызывает метод итератора next()
, пока он не вернет nil
:
var it = values.makeIterator()
while let s = it.next() {
print(s)
}
Ваша вторая версия эквивалентна
var it = values.makeIterator()
while let s: String? = it.next() {
print(s)
}
и теперь компилятор предупреждает:
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
Итак, что здесь происходит, это то, что String?
вернулся с it.next()
оборачивается в «вложенный необязательный» .some(it.next())
типа String??
, который затем необязательно связывается с s: String?
.
Это всегда успешно, потому что .some(it.next())
не является String??.none
.
Поэтому цикл никогда не завершается.
Можно утверждать, что компилятор должен также предупреждать о
for s: String? in values {
print(s)
}