一,概述
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更廣