一,概述
Swift摒弃了C语言式定义变量、累加变量的for-loop,用for-in
取而代之,来遍历集合类型。那什么是
forEach(_:)
呢?
forEach(_:)
也是一种遍历方式。虽然都是遍历方式,但是两者还是有些许的不同的。
二,for in 与 forEach
for-in
- 不需要使用索引,只是单纯的遍历集合
/*! 单纯的遍历集合*/ let strs = ["first","second","third"] for str in strs { print(str) } /* 打印: first second third */
- 需要使用索引
let strs = ["first","second","third"] for (index,str) in strs.enumerated() { print("\(index) --- \(str)") } /* 打印: 0 --- first 1 --- second 2 --- third */
forEach(_:)
- 函数式编程
let arr = ["1","2","3"] arr.map{Int($0)!}.forEach{(num) in print(num)} /*打印: 1 2 3 */
假如不使用forEach
let arr = ["1","2","3"] let map = arr.map {Int($0)!} for num in map { print(num) } /* 打印: 1 2 3 */
- 遍历optional的集合类型
如果使用for-in强制解包的话会crash
var optionalStrs:[String]? = nil for str in optionalStrs! { print(str) }
使用forEach比较便捷,不会crash
var optionalStrs:[String]? = nil optionalStrs?.forEach({ (str) in print(str) })
三,同类型的泛型集合
-
for in
let array = ["1", "2", "3", "4", "5"] for element in array { print(element) } /* 打印: 1 2 3 4 5 */
- forEach
let array = ["1", "2", "3", "4", "5"] array.forEach { (element) in print(element) } /* 打印: 1 2 3 4 5 */
- 结论
在集合的 元素类型相同(比如上面的数组是 String类型)的情况下,两者遍历效果相同,方便、敏捷,我们可以随意选用。
四,不同类型元素的集合
- for in
//⚠️ as [Any]是swift 3的语法要求,因为数组中有两种不同类型的元素,分别是:Int 、String, 所以需要转化成 [Any]类型 let array = [1, 2, 3, "cat", "rabbit"] as [Any] for element in array { print(element) } /* 打印: 1 2 3 cat rabbit */
- forEach
//⚠️ as [Any]是swift 3的语法要求,因为数组中有两种不同类型的元素,分别是:Int 、String, 所以需要转化成 [Any]类型 let array = [1, 2, 3, "cat", "rabbit"] as [Any] array.forEach { (element) in print(element) } /* 打印: 1 2 3 cat rabbit */
- 结论
在集合的元素类型不相同(比如上面的数组是Int和String类型)的情况下,两者遍历效果相同,方便、敏捷,我们可以也随意选用。
五,return关键字
- for in
func testMethods(){ let array = ["1", "2", "3", "4", "5"] for element in array { if element == "3" { return } print(element) } print("Hello World") } testMethods() /* 打印: 1 2 */
- forEach
func testMethods(){ let array = ["1", "2", "3", "4", "5"] array.forEach { (element) in if element == "3" { return } print(element) } print("Hello World") } testMethods() /* 打印: 1 2 4 5 */
- 结论:
在使用 return关键字的时候,很明显,
for in
中是当符合当前执行语句时,程序直接终止到此并返回, 比如上面的元素 "4"、 "5"、 "Hello World" 没有被执行;而forEach
中是当符合当前执行语句时,程序跳过本次判断继续执行, 比如上面的元素 "4"、 "5"、 "Hello World"被执行。
六,continue关键字
- for in
func testMethods(){ let array = ["1", "2", "3", "4", "5"] for element in array { if element == "3" { continue } print("element is \(element)") } print("Test \"continue\"") } testMethods() /* 打印: element is 1 element is 2 element is 4 element is 5 */
- forEach
func testMethods(){ let array = ["1", "2", "3", "4", "5"] array.forEach { (element) in if element == "3" { continue } print(element) } print("Test \"continue\"") } testMethods() /* 错误: 程序根本不能执行 error:continue is only allowed inside a loop */
- 结论
在使用 continue关键字的时候,
for in
可以正常遍历并且执行,而且 continue的作用是跳出本次循环,不影响后面的执行; 而在forEach
中, swift是不允许这样执行的,报错的原因是说 continue只允许出现在循环语句中,也就是说不能使用在forEach
的 closure中。
七,break关键字
- for in
func testMethods(){ let array = ["1", "2", "3", "4", "5"] for element in array { if element == "3" { break } print("element is \(element)") } print("Test \"continue\"") } testMethods() /* 打印 element is 1 element is 2 Test "continue" */
- forEach
func testMethods(){ let array = ["1", "2", "3", "4", "5"] array.forEach { (element) in if element == "3" { break } print(element) } print("Test \"continue\"") } testMethods() /* 错误:程序根本不能执行 error:Unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do */
- 结论
在 break关键字中,对于
for in
来说是可以的,跳出本层循环,也就是 for循环,然后继续执行后面的程序; 对于forEach
来说,同 continue关键字的效果一样, swift不允许这样使用,原因说的是 break只能用于循环语句或 switch语句, break会退出本层循环语句。
八,Apple官方对 forEach 的说明
- 下面是Apple的官方文档解释,对forEach遍历方法做了个大致的介绍,有兴趣可以看一下
/// Calls the given closure on each element in the sequence in the same order /// as a `for`-`in` loop. /// /// The two loops in the following example produce the same output: /// /// let numberWords = ["one", "two", "three"] /// for word in numberWords { /// print(word) /// } /// // Prints "one" /// // Prints "two" /// // Prints "three" /// /// numberWords.forEach { word in /// print(word) /// } /// // Same as above /// /// Using the `forEach` method is distinct from a `for`-`in` loop in two /// important ways: /// /// 1. You cannot use a `break` or `continue` statement to exit the current /// call of the `body` closure or skip subsequent calls. /// 2. Using the `return` statement in the `body` closure will exit only from /// the current call to `body`, not from any outer scope, and won't skip /// subsequent calls. /// /// - Parameter body: A closure that takes an element of the sequence as a /// parameter.
-
小结:
- for in 能使用 return、break、continue关键字,forEach不能使用 break、continue关键字
- for in 和 forEach 在 return关键字 的使用上有着本质的区别
- 一般情况下,两者都可通用,都方便、敏捷
- for in 使用范围比 forEach更广