微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

令人惊讶的结果是在Swift中使用可选项迭代数组

我很惊讶这个快速代码行为很好:

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] 举报,一经查实,本站将立刻删除。

相关推荐