swift小知识点之Swift中遍历方法for in 和 forEach的区别


一,概述

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
     */
  • 结论

    在集合的元素类型不相同(比如上面的数组是IntString类型)的情况下,两者遍历效果相同,方便、敏捷,我们可以也随意选用。

五,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只允许出现在循环语句中,也就是说不能使用在  forEachclosure中。

七,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更广

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM