Swift 因为in-loop走得太远,找到了';无';拆开包装时

Swift 因为in-loop走得太远,找到了';无';拆开包装时,swift,for-loop,for-in-loop,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) } 我一定是遗漏

下面的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)
}
我一定是遗漏了什么。
list.count不应该是for-in循环尝试展开的元素数吗

如上图所示,如果使用
[Int]
列表而不是
[Int?]
而无需展开,则for in循环将按预期工作


我使用的是Swift 2.1.1版。

x:Int一样强制展开是一种危险的编码样式。这同样适用于
var x:Int=list[i]

这项工作:

print("\nFor-in loop")
for x in list {
   print(x)
}
在这里,您允许x为零,并且可以稍后安全地检查零

现在,请回答为什么代码会中断的问题:


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

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

现在是解决办法。很明显,您正试图用
Int打开包装。要安全地展开,请对大小写使用
语法:

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
}
另一种方法(相同的结果):


这里有些奇怪的行为。如果将
list
标记为
[Int]
,然后将
x
标记为
Int?
,in
循环将永远打印
nil
。@Robert如果您了解它的工作原理,这种行为并不特别奇怪。。。但是Swift可能应该简单地防止
x
被作为这样的可选标签(因为它只会导致无限循环)。你能简单地解释一下发生了什么吗?为什么这会形成一个无限循环?@Robert我对你刚才问的问题的回答并不完全涵盖这个解释,但我愿意回答你的问题。。。但在评论中这样做有点困难。也许有了这个解释,你就有了足够的信息来理解它。但问题是,这会产生可选的(1),可选的(2),等等,这不是OP想要的。你是对的。我怀疑打印只是为了调试,OP显然知道如何打开。对我来说,更有趣的问题是为什么它失败了。所以forEach也遇到了同样的问题。。。吓人。@Darko不,事实上不是这样;这给了我另一个解决方案——简单的
list.forEach{print($0!)}
工作(当然,由于其他原因它可能有危险)是的,但是list.forEach{print($0)}也会崩溃。这里对平面图的需求让我害怕。
case let x中的问号是什么?在列表中
是非常不直观的。我不知道在斯威夫特的其他地方我们在哪里像那样展开。我也认为
(同样的结果)
至少有点误导。Playdey建议,答案底部的替代解决方案要昂贵得多:(对于包含13个元素的数组,6个零)。
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