Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 何时使用forEach(:)而不是for in?_Swift_Loops_Foreach_Sequence_For In Loop - Fatal编程技术网

Swift 何时使用forEach(:)而不是for in?

Swift 何时使用forEach(:)而不是for in?,swift,loops,foreach,sequence,for-in-loop,Swift,Loops,Foreach,Sequence,For In Loop,如和forEach(:)实例方法中所述: 对序列中的每个元素调用给定的闭包 作为for-in循环的顺序 然而,改编自: 序列是一系列的值,您可以一步一步地通过这些值 时间迭代序列元素的最常用方法 是将用于in-loop 这意味着通过forEach(:)或对in进行迭代序列: let closedRange = 1...3 for element in closedRange { print(element) } // 1 2 3 closedRange.forEach { print($0)

如和
forEach(:)
实例方法中所述:

序列中的每个元素调用给定的闭包 作为for-in循环的顺序

然而,改编自:

序列是一系列的值,您可以一步一步地通过这些值 时间迭代序列元素的最常用方法 是将用于in-loop

这意味着通过
forEach(:)
对in进行迭代序列:

let closedRange = 1...3

for element in closedRange { print(element) } // 1 2 3

closedRange.forEach { print($0) } // 1 2 3
或(数组):

将给出相同的输出

为什么
forEach(:)
甚至存在?i、 e使用它而不是
for in
循环有什么好处?从性能角度看,它们是否相同


作为一种假设,它可能是一种语法糖,尤其是在使用函数式编程时。

forEach
没有提供任何性能优势。实际上,
forEach
函数实际上只是在中为-
执行
。对于发布版本,仅在
中为
-
使用该函数的性能开销是无关紧要的,但是对于调试版本,它会导致明显的性能影响

forEach
的主要优点是,在进行函数式编程时,可以将其添加到函数调用链中,而无需将先前的结果保存到单独的变量中,如果在
语法中使用
for
-
,则需要使用该变量。因此,不是:

let objects = array.map { ... }
    .filter { ... }

for object in objects {
    ...
}
相反,您可以停留在函数式编程模式中:

array.map { ... }
    .filter { ... }
    .forEach { ... }
结果是函数代码更简洁,语法噪音更小

FWIW、forEach的文档以及所有这些文档都提醒我们forEach引入的限制,即:

  • 不能使用
    break
    continue
    语句退出当前操作 调用
    正文
    结束或跳过后续调用

  • 使用
    body
    闭包中的
    return
    语句将仅从 当前对
    body
    的调用不是从任何外部作用域进行的,并且不会跳过 随后的电话


  • 它们或多或少是可互换的,但有两个重要的区别

  • break
    /
    continue
    仅在
    中工作,用于。。在
  • forEach
    中的
    return
    将退出闭包,但不会停止迭代
  • 原因是。。in
    是该语言中的一种特殊形式(它允许中断并继续按预期工作)。这是您无法使用语言本身以相同的方式实现的

    但是,
    forEach
    不是一种特殊的形式,可以通过将其作为函数编写来重新实现

    extension Sequence {
        func myOwnForEach(_ body: (Self.Element) throws -> Void) rethrows {
            let it = Self.makeIterator()
            while let item = it.next() {
                body(item)
            }
        }
    }
    

    我最近遇到了一个用例,其中使用
    forEach
    比使用
    for in
    更可取。假设要从层中删除所有子层。下面这样的语句不起作用,因为您需要打开
    [CALayer]

    for layer in self.videoContainerView.layer.sublayers!
    
    如果子层为零,则会发生崩溃。这迫使您首先检查是否存在子层。但是,forEach的
    forEach
    使其变得更简单,如下所示:

    self.videoContainerView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
    

    除了上述答案之外,将
    for
    循环与
    forEach
    区别开来的另一个原因是,对于
    for
    循环,我们还可以选择使用基于
    的模式匹配来实现该逻辑,如

    for adBanner in adBanners where !adBanner.isLoading {
    
    上面那种与控制流相关的特性使得for循环功能强大,但是如果我们不需要那种级别的控制,使用forEach调用可能会使代码看起来稍微简单一些


    因此,简而言之,使用
    for
    循环可以让我们对迭代进行更大程度的控制

    从性能角度来看
    forEach
    for循环
    慢。但它也可以方便地用作Objective-C的
    makeObjectsPerformSelector:
    @vadian的等价物-在调试构建中,它要慢得多。在发布版本中未必如此(显然,这取决于代码中的其他内容)。例如,我刚刚通过发布版本中包含数百万个对象的阵列对迭代进行了基准测试,性能差异是无法区分的。@Rob感谢您的反馈。事实上,我的“基准测试”是在调试模式下执行的(仅此而已)⌘运行项目)谢谢@Rob。这是否意味着我们应该只在函数式编程中使用
    forceah
    。这是一个很好的简明语法,您可以在任何地方使用。我只是想说,它最大的效用是当与函数式编程结合使用时,与此相反,
    模式中的
    for
    -
    实际上变得相当麻烦。@Rob根据您的建议,我发布了一个与此相关的衍生问题。关于链接的观点很好。这对我来说并不明显,我想去几个地方皈依。forEach就是因为这个原因。
    
    for adBanner in adBanners where !adBanner.isLoading {