• Swift --闭包表达式与闭包(汇编分析)


    在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数!

    一、闭包表达式

    概念

    闭包表达式与定义函数的语法相对比,有区别如下:

    1. 去除了func
    2. 去除函数名
    3. 返回值类型添加了关键字in
    4. { }放在形参列表的前边

    闭包表达式的形式如下:

    { 
    
       (参数列表) -> 返回值类型 in
    
         函数体代码
    
     }

    讲解

    举例1  闭包表达式作为变量或者常量的值

     调用闭包表达式不需要写参数v1,v2,直接调用fn0(10,20)就可以

    举例2 闭包表达式作为函数的返回值

    举例3 闭包表达式作为函数的实参

    下面讲述sorted(by:)方法定义和语法优化方式,来展示闭包表达式不同的表达方式达到同样的效果!

    讲述之前先简单介绍下sorted方法, Swift标准库提供了sorted(by:)方法,会将已知类型数组中的值进行排序. 一旦进行了排序会返回和原数组大小相同,包含同类型元素并且是正确排序的数组,如例3. 

    sorted(by:)方法接受一个闭包,该闭包函数需要传入元素类型的两个值,并返回Bool值,完成排序,排序闭包函数类型需为(String, String) -> Bool

    在上面的两种写法中,都写成了(String, String) -> Bool, 在闭包表达式中函数和返回值类型都写在了大括号内,而不是大括号之外.

    下面不断简化的如下

    let arr = ["hello","world","guohai"]
    ///闭包表达式当做参数
    //写法一
    let sortArr0 = arr.sorted{(str1: String, str2: String) -> Bool in
        return str1 < str2
    }
    //写法二: 省去了参数类型
    let sortArr1 = arr.sorted{(str1, str2) -> Bool in
        return str1 < str2
    }
    //写法三: 如果返回值是单一表达式,可省去return
    let sortArr2 = arr.sorted{(str1, str2) -> Bool in
        str1 < str2
    }
    //写法四: 如果编译器可以确定返回值,可以去除返回值类型
    let sortArr3 = arr.sorted{(str1, str2) in
        str1 < str2
    }
    //写法四: Swift闭包表达式可以不明显写出参数名,可以用美元符$表示
    let sortArr4 = arr.sorted{$0 < $1}
    //写法五: 编译器,对于$0 < $1和直接<效果一样
    let sortArr5 = arr.sorted(by: <)

    尾随闭包

    如果将很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性

    尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式

     如果闭包表达式是函数的唯一实参,而且使用了尾随闭包的语法, 那就不需要在函数名后写圆括号

    二、闭包

    闭包: 一个函数和它所捕获的变量/常量环境组合起来

    • 一般指定义在函数内部的函数
    • 一般它捕获的是外层函数的局部变量/常量

    看如下闭包,返回的plus和num形成了闭包

    typealias Fn = (Int) -> Int
    func getFn() -> Fn {
        var num = 0
        func plus(_ i: Int) ->Int {
            num += i
            return num
        }
        return plus
    }
    var fn = getFn()
    print(fn(1))
    print(fn(2))
    print(fn(3))
    print(fn(4))

    如果大家看不出上面的结果,可以将var num = 0放在外面是全局变量,如下

     全局变量num时,结果是不断的叠加,如果还是回到上一个,将num = 0移植到函数内部变成局部变量,和plus形成闭包,结果又如何呢? 

     发现结果是一样的,下面来探究本质!

    查看上面代码汇编代码如下

     上面四次fn操作,调用访问的同一内存num,因为闭包的作用将局部变量num放进了堆空间,所以num不会被销毁!

    拓展:(iOS底层堆空间分配的大小是16的倍数--常识)

  • 相关阅读:
    华为实习日记——第三十八天
    华为实习日记——第三十七天
    华为实习日记——第三十六天
    华为实习日记——第三十五天
    华为实习日记——第三十四天
    华为实习日记——第三十三天
    华为实习日记——第三十二天
    华为实习日记——第三十一天
    华为实习日记——第三十天
    一些事情(征标题)
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/12421590.html
Copyright © 2020-2023  润新知