For-in 循环走得太远并在展开时找到 'nil'

For-in loop goes one-too-far and finds 'nil' while unwrapping

看起来下面的 Swift for-in 循环试图遍历比数组中更多的元素。

例如,这段代码:

var list:[Int?] = [1,2,3,4,5,6,7]

print("C-Style for loop")
for var i=0; i<list.count; i++ 
{
    var x:Int = list[i]!
    print(x)
}

print("\nFor-in loop")
for var x:Int! in list
{
    print(x)
}

得到这个输出:

C-Style for loop
1
2
3
4
5
6
7

For each loop
1
2
3
4
5
6
7
fatal error: unexpectedly found nil while unwrapping an Optional value
... 
Illegal instruction: 4

我一定是漏掉了什么。 list.count 不应该是 for-in 循环尝试解包的元素数吗?

如上图所示,如果使用 [Int] 列表而不是 [Int?] 且没有展开,for-in 循环将按预期工作。

我正在使用 Swift 版本 2.1.1。

当您不能排除 nil 时,像 x:Int! 那样的强制展开是一种危险的编码风格。 var x:Int = list[i]! 也是如此。

这个有效:

print("\nFor-in loop")
for x in list {
   print(x)
}

在这里您允许 x 为 nil,稍后可以安全地检查 nil。

现在回答你的代码为什么会出错的问题:

在内部,swift 使用 list.generate() 作为 for-in 循环。生成器没有终止,这可能是您的代码中断的原因。

基本上你做了一些你不应该做的事情,因此你偶然发现了一些可能是编译器错误的东西(因为编译器没有阻止你)。很不错!

现在解决。您显然是在尝试用 Int! 解包。要安全地解包 ,请使用 for case 语法:

let list:[Int?] = [1,2,3,4,5,6,7]
for case let x? in list
{
    print(x) // 1, 2, 3, 4, 5, 6, 7
}

另一种方式(结果相同):

let list:[Int?] = [1,2,3,4,5,6,7]
list.flatMap{[=11=]}.forEach{print([=11=])} // 1, 2, 3, 4, 5, 6, 7