我很惊讶这个快速的代码行为很好:
let values = ["Hello","Test"] var count = 0 for string: String in values { count = count + 1 print("count is: ",count) print(string) }
输出:
count is: 1 Hello count is: 2 Test
但将String变为String?创造一个无限循环.
let values = ["Hello","Test"] var count = 0 for string: String? in values { count = count + 1 print("count is: ",count) print(string) }
输出:
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非常擅长捕捉奇怪的代码问题,我很惊讶我可以在没有警告或错误的情况下陷入如此混乱.
这真的是人们对Swift 4的期望吗?如果是这样,为什么?
解决方法
要理解这个问题,有助于回忆for-for循环的工作原理:
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) }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。