在 Swift 中使用可选项迭代数组的结果令人惊讶
Surprise results iterating over an array with an optional in Swift
令我惊讶的是这段 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
但是把字符串变成字符串?创建一个无限循环。
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" 在索引上运行。索引下超过元素个数为nill。
没有错误。在第一个函数中,它将继续运行直到不再有字符串。
但另一方面,您将字符串设置为可选的第二个函数,因此当它不再有字符串时,它仍会继续运行。因为 nil 是一个 nil 值,它不等于没有。你没有任何东西可以结束那个循环。
为了理解这个问题,回忆一下 for-in 循环是如何工作的:
for s in values {
print(s)
}
创建序列的迭代器,并调用迭代器的next()
方法直到returns 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()
返回
被包装成 String??
类型的“嵌套可选”.some(it.next())
,然后可选地绑定到 s: String?
。
这总是成功的,因为 .some(it.next())
不是 String??.none
。
因此循环永远不会终止。
有人可能会争辩说编译器也应该对
发出警告
for s: String? in values {
print(s)
}
令我惊讶的是这段 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
但是把字符串变成字符串?创建一个无限循环。
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" 在索引上运行。索引下超过元素个数为nill。
没有错误。在第一个函数中,它将继续运行直到不再有字符串。
但另一方面,您将字符串设置为可选的第二个函数,因此当它不再有字符串时,它仍会继续运行。因为 nil 是一个 nil 值,它不等于没有。你没有任何东西可以结束那个循环。
为了理解这个问题,回忆一下 for-in 循环是如何工作的:
for s in values {
print(s)
}
创建序列的迭代器,并调用迭代器的next()
方法直到returns 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()
返回
被包装成 String??
类型的“嵌套可选”.some(it.next())
,然后可选地绑定到 s: String?
。
这总是成功的,因为 .some(it.next())
不是 String??.none
。
因此循环永远不会终止。
有人可能会争辩说编译器也应该对
发出警告for s: String? in values {
print(s)
}