Swift-闭包Closure

先复习一下函数Swift-func

闭包可以定义一个函数

闭包可以定义一个函数

闭包可以定义一个函数

闭包概念:

  • 一个函数和它所捕获的变量/常量环境组合起来,称为闭包
  • 一般指定义在函数内部的函数
  • 一般它捕获的是外层函数的局部变量/常量

演绎过程:

typealias Fn = (Int) -> Int
func getFn() -> Fn {
    var num = 10
    func plus(i: Int) -> Int {
        num += I
        return num
    }
    return plus//这是函数哦 不能是实现
    return plus(I:)
}

var fnx = getFn()
print(fnx(1))
  • 2层函数 外层函数getFn返回值是函数类型 内层函数plus也要返回函数类型
  • plus函数和num形成了闭包

简易一下程序

func getFn() -> Fn {
    var num = 10
    return {
        num += $0
        return num
    }
}

类比一个类的实例对象

  • 内存在堆空间
  • 捕获的局部变量/常量就是对象的成员(存储属性)
  • 组成闭包的函数 就是类内部定义的方法
class Closure {
    var num = 0
    func plus(_ i:Int) -> Int {
        num += I
        return num
    }
}
var cs1 = Closure()
print(cs1.plus(1))

闭包

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

func add(_ v1: Int,_ v2: Int) -> Int {
    v1 + v2
}
var fx = {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
}
print(fx(10,20))
print(fx)
print(add)

把实现带着随便测试
var fx1 = {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
}(10,10)
print(fx1)
  • 上面打印fx 打印结果: (Function)
  • 上面打印add 打印结果: (Function)
  • 闭包类似add 然后调用它 传入参数fx(10,20)
image.png

闭包作为参数(闭包简写真特么简 其实不简写容易读)

//exec定义
func exec(v1: Int,v2: Int,fn:(Int,Int) -> Int) {
    print(fn(v1,v2))
}

实现exec方法

  • 普通函数
var fn:(Int,Int)->Int = add
exec(v1: 10, v2: 10, fn: fn)
  • 闭包
//写全一点
exec(v1: 10, v2: 20, fn: {
    (v1: Int,v2: Int) -> Int in
    return v1 + v2
})
//省略return
exec(v1: 10, v2: 20, fn: {
    (v1: Int,v2: Int) -> Int in
    v1 + v2
})
//省略参数
exec(v1: 10, v2: 20, fn: {
    v1,v2 -> Int in
    v1 + v2
})
//省略返回值
exec(v1: 10, v2: 20, fn: {
    v1,v2  in
    v1 + v2
})
//下标
exec(v1: 10, v2: 10, fn: {
    $0 + $1
})
//一步到位了靠
exec(v1: 10, v2: 10, fn: +)

尾随闭包

  • 如果将一个很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性
  • 尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式
  • 如果闭包表达式是函数的唯一实参,而且使用了尾随闭包的语法,那就不需要在函数名后面写圆括号
func exec1(fn:(Int,Int) -> Int) {
    print(fn(1,2))
}
exec1(fn: {
    (v1: Int,v2: Int) -> Int in
    return v1 * v2
})
exec1{
    (v1: Int,v2: Int) -> Int in
    return v1 * v2
}
......下面同样可以省略 自己搞吧

自动闭包(语法真鸡贼)

后面在搞吧 语法真特么难懂太简易了

  • @autoclosure 会自动将20 封装成闭包{20}
  • @autoclosure 只支持 () -> T 格式的参数
  • @autoclosure 并非只支持最后一个参数
  • 空合并运算符?? 使用了@autoclosure技术
  • 有@autoclosure 无@autoclosure,构成了函数重载
  • 为了避免与期望冲突,使用了@autoclosure的地方最好明确注释清楚,这个值会被推迟执行
func getFirstPositive (_ v1: Int,_ v2: Int) -> Int {
    return v1 > 0 ?v1 : v2
}
print(getFirstPositive(10, 20))
print(getFirstPositive(-2, 20))
print(getFirstPositive(0, -4))
//改成函数类型的参数,可以让v2延迟加载
func getFirstPositive(_ v1: Int,_ v2: () -> Int) -> Int? {
    return v1 > 0 ? v1: v2()
}
print(getFirstPositive(-4, {20})!)

func getFirstPositive1(_ v1: Int,_ v2:@autoclosure () -> Int) -> Int? {
    return v1 > 0 ? v1: v2()
}
print(getFirstPositive1(-4, 20)!)

参数修饰符保持一致

//如果返回值是函数类型,那么参数的修饰要保持统一
func total(_ num: Int) -> (inout Int) -> Void {
    func plus(v: inout Int) {
        v += num
    }
    return plus
}
var vvvv = 5
total(20)(&vvvv)
print(vvvv)

忽略参数(语法真鸡贼)

func exec2(fn:(Int ,Int) -> Int) {
    print(fn(1,2))
}
exec2{_,_ in 100}

练习

var functions:[() -> Int] = []
for i in 1...3 {
    functions.append{I}
}
for i in functions {
    print(i)
}
class Closure2 {
    var i: Int
    init(_ i: Int) {
        self.i = I
    }
    func get() -> Int {
        return I
    }
}
var clses:[Closure2] = []
for i in 1...3 {
    clses.append(Closure2(i))
}
for i in clses {
    print(i.get())
}

补充案例

案例一:网络请求 省略参数 逃逸闭包

image.png

Function types cannot have argument labels; use '_' before 'result'
从Swift3.0开始, 苹果官方建议方法中函数类型的参数不要带参数名称, 尤其是不能带外部参数名.
解决方案:

  • 省略标签参数
  • 这个闭包里面的标签参数是为了增加代码可读性
class func requestData(parameters: [String:Any]?,finishedCallBack:(_ result:Any)->()) {
    finishedCallBack("回调请求内容")
}

新的问题


image.png

逃逸闭包捕获非逃逸闭包
captures:捕获
Escaping:逃逸


image.png

语法小计

  • 闭包实现 可以把参数省略
NetworkTools.requestData(url: requestUrl, method: .post, parameters: parameters) { response, status in
    
}
NetworkTools.requestData(url: requestUrl, method: .post, parameters: parameters) { (response, status) in
    
}

你可能感兴趣的:(Swift-闭包Closure)