循环中Swift样式的多个增量

时间:2016-03-23 16:25:46

标签: swift swift3

我的Swift代码中有以下循环:

chown --recursive blog:blog "$WORDPRESS_DIR"

我在Xcode中收到两个警告:

  1. 不推荐使用C-style for语句,将在未来的Swift版本
  2. 中删除
  3. ' ++'不推荐使用:它将在Swift 3中删除
  4. 我无法看到如何在Swift的For In Loops中重写这一点,以考虑两个变量和4步,而不会让它变得混乱。有简单优雅的翻译吗?

2 个答案:

答案 0 :(得分:15)

回答这个问题的先决条件:查看你的例子

我假设您打算将i限制为i < rawDataOut.count-3而不是i < rawDataOut.count,否则rawDataOut[i + 3]元素按索引访问将不会有任何意义w.r.t.运行时安全。无论如何,如果没有向我们展示rawDataOut,这是我们必须做出的假设。

因此,您的原始循环(包括可验证的示例)如下所示

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* your pre-Swift 2.2/3.0 loop */
for var i: Int = 0, j: Int = 0; i < rawDataOut.count-3; i += 4, ++j {
    maskPixels[j] = rawDataOut[i + 3]
}

print(maskPixels) //[4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

使用for in ... where

在您的特定示例情况下,多个增量具有简单的关系(j=4*i),因此我们甚至无需使用显式j迭代就可以解决此问题,例如

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* your pre-Swift 2.2/3.0 loop */
for i in 0..<(rawDataOut.count-3) where i%4 == 0 {
    maskPixels[i/4] = rawDataOut[i + 3]
}

print(maskPixels) // [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

但对于两次迭代的一般讨论,这可能不是真正有意义的。我们将结合使用strideenumerate的双迭代方法。

合并strideenumerate

一种解决方案是枚举上面循环中迭代stride描述的i,并使用枚举索引构造第二个迭代(上面的j)。在您的示例中,enumerate索引与j完全对应,即

/* example data */
var rawDataOut = Array(1...40)
var maskPixels = [Int](count: 10, repeatedValue: 0)

/* Swift >= 2.2 loop */
for (j, i) in 0.stride(to: rawDataOut.count-3, by: 4).enumerate() {
    maskPixels[j] = rawDataOut[i + 3]
}

print(maskPixels) // [4, 8, 12, 16, 20, 24, 28, 32, 36, 40]

请注意,在Swift 3中(与2.2相比),似乎stride(to:by:)stride(through:by:)到协议Strideable的默认实现(作为非蓝图扩展方法)被剥夺,我们使用全局函数stride(from:to:by:)stride(from:through:by:)返回(如在Swift 1.2中),参见eg swift/stdlib/public/core/Stride.swift

的当前主分支

棘手的案例:诉诸while

对于更棘手的情况,请在Swift 2.2之前的循环中标注为

for var i: Int = 0, j: Int = 0; i < rawDataOut.count-3; i += 4, j += i { ... }

你可能最好只使用while循环,其中一个迭代与循环不变量相关联,并且尾随迭代作为自由变量;我想,这是否被认为是杂乱无味的问题。

var i = 0, j = 0
while i < rawDataOut.count-3 {

    // ...

    // increase iterates
    i += 4
    j += i
}

我认为删除C风格循环的原因是它在大多数情况下直接由for instride等覆盖,并且对于这些循环,&#39足够了,一个好老的&#39;最有可能的是while

答案 1 :(得分:4)

在Swift 4中

private void DesignerPanel_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    // do something
}