Ahm*_*d F 26 foreach loops sequence for-in-loop swift
以与for-in循环相同的顺序调用序列中每个元素的给定闭包.
然而,改编自序列概述:
序列是一个值列表,您可以一次单步执行一个值.迭代序列元素的最常用方法是使用for-in循环.
暗示通过forEach(_:)或迭代序列for in:
let closedRange = 1...3
for element in closedRange { print(element) } // 1 2 3
closedRange.forEach { print($0) } // 1 2 3
Run Code Online (Sandbox Code Playgroud)
或(数组):
let array = [1, 2, 3]
for element in array { print(element) } // 1 2 3
array.forEach { print($0) } // 1 2 3
Run Code Online (Sandbox Code Playgroud)
会给出相同的输出.
为什么forEach(_:)甚至存在?即使用它代替for in循环有什么好处?从性能观点来看它们是否相同?
作为一个假设,它可能是一个语法糖,特别是在使用函数式编程时.
Rob*_*Rob 59
没有提供的性能优势forEach.事实上,如果你看一下源代码,这个forEach函数实际上只是简单地执行for- in.对于发布版本,此函数的性能开销仅仅使用for- in自己是无关紧要的,但对于调试版本,它会导致可观察到的性能影响.
forEach当您进行函数式编程时,可以实现主要优点,您可以将其添加到函数调用链中,而无需将先前结果保存到您使用的单独变量中for- in语法.所以,而不是:
let objects = array.map { ... }
.filter { ... }
for object in objects {
...
}
Run Code Online (Sandbox Code Playgroud)
您可以保持在函数式编程模式中:
array.map { ... }
.filter { ... }
.forEach { ... }
Run Code Online (Sandbox Code Playgroud)
结果是功能代码更简洁,语法噪音更少.
FWIW,Array,Dictionary和Sequence的文档都提醒我们引入的限制forEach,即:
您不能使用
breakorcontinue语句退出当前的body闭包调用或跳过后续调用.使用闭包中的
return语句body将仅从当前调用退出body,而不是从任何外部作用域退出,并且不会跳过后续调用.
pli*_*nth 11
它们或多或少可以互换,但有两个重要的区别.
break/ continue只在一个for .. inreturn在forEach将退出关闭,但不会停止迭代.原因在于它for .. in是语言中的一种特殊形式(允许中断并继续按预期工作).这是你无法使用语言本身以相同的方式实现的东西.
但是,forEach它不是一种特殊形式,可以通过将其写为函数来重新实现.
extension Sequence {
func myOwnForEach(_ body: (Self.Element) throws -> Void) rethrows {
let it = Self.makeIterator()
while let item = it.next() {
body(item)
}
}
}
Run Code Online (Sandbox Code Playgroud)
C6S*_*ver 11
我最近碰到了一个用例,其中使用forEach是有形的for in.假设您要从图层中删除所有子图层.如下所示的声明不起作用,因为您需要打开包装[CALayer]
for layer in self.videoContainerView.layer.sublayers!
Run Code Online (Sandbox Code Playgroud)
如果子层为零,则会发生崩溃.这会强制您先检查是否有子图层.但是,a forEach使这更简单,如下所示:
self.videoContainerView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
Run Code Online (Sandbox Code Playgroud)