用于递增和递减循环的新 Swift for-in 语法

New Swift for-in syntax for incrementing and decrementing loops

TL;DR;为什么 Swift 范围运算符不处理递减范围?

我有一些这样的代码:

for var i = 0; i < previousPage; i += 1 {
    purgePage(i)
}

swift 编译器建议我更改为 new Swift for loop 语法:

C-style for statement is deprecated and will be removed in a future version of Swift
Fix-it Replace "var i = 0; i < previousPage; i += 1" with "i in 0 ..< previousPage"

生成的代码现在如下所示:

// Purge previous non-visible pages.
for i in 0 ..< previousPage {
    purgePage(i)
}

问题是现在应用程序崩溃了,因为 previousPage 可以是负整数或正整数,形成递增或递减的范围。当范围减小时,我得到 EXC_BAD_INSTRUCTION:

fatal error: Can't form Range with end < start

如何使新语法适用于我的情况?添加代码来检查 previousPage 的值似乎是对旧语法的倒退。

您可以使用 stride 而不是范围。在这种情况下它不会崩溃。

0.stride(to: previousPage, by: 1).forEach { purgePage([=10=]) }

从错误中可以得出结论,循环方向错误,例如 0..-4 或 6...1。

要解决问题,可以使用 do while,这不是最好的解决方案,但简单明了:

var i = 0;

while i < previousPage{
    i += 1
    print(i)
}

我认为最好的办法是在循环之前手动添加一个条件。从功能上讲,这应该类似于 C 风格的循环;但是,它在语法上并不简洁:

if (previousPage > 0)
{
    // Purge previous non-visible pages.
    for i in 0 ..< previousPage {
        purgePage(i)
    }
}

Why doesn't the Swift range operator handle decreasing ranges?

我相信我读过 Swift 团队成员(可能是 @jckarter)的声明,他们故意以这种方式设计 Range 以避免可能的程序员错误来源。原因通常是,当您从 a..<b 等变量(而非文字)创建范围时,您会隐含地假设 a <= bRange 旨在捕捉是否违反该假设以使(可能的)错误对您显而易见的情况。

虽然我现在找不到参考资料。