For-in循环过于远,在展开时发现'nil'

时间:2016-03-27 19:58:52

标签: swift for-loop for-in-loop

看起来下面的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

我必须在这里遗漏一些东西。 {for} for try尝试解包的元素数量不应该list.count吗?

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

我使用的是Swift 2.1.1版。

2 个答案:

答案 0 :(得分:4)

基本上你已经完成了一些你不应该做的事情,因此你偶然发现了一些可能是编译器错误的东西(因为编译器没有停止您)。非常好!

现在的解决方案。你显然是想用你的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{$0}.forEach{print($0)} // 1, 2, 3, 4, 5, 6, 7

答案 1 :(得分:2)

x:Int!这样的强制展开是一种危险的编码风格,当你不能排除零时。同样适用于var x:Int = list[i]!

这有效:

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

这里你允许x为零,并且可以安全地检查nil。

现在问你代码中断的原因:

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