IOS开发Swift笔记09-闭包

闭包表达式

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

func sun(_ v1: Int, _ v2: Int) -> Int {v1 + v2}

var fn = {
    (v1: Int, v2: Int) -> Int in
    return v1 + v2
}

print(fn(10, 20))

var a = {
    (v1: Int, v2: Int) -> Int in
    return v1 + v2
}(10, 10)

print(a)

/*
闭包表达式
{
    (参数列表) -> 返回值 in
    函数体代码
}
/*

闭包表达式的简写

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

exec(v1: 10, v2: 20) { (v1: Int, v2: Int) -> Int in
    return v1 + v2
}

exec(v1: 10, v2: 10) { (v1, v2) -> Int in
    return v1 + v2
}

exec(v1: 10, v2: 30) { v1, v2 in
    return v1 + v2
}

exec(v1: 10, v2: 40) { v1, v2  in
    v1+v2
}

exec(v1: 10, v2: 50, fn: {$0 + $1})

exec(v1: 10, v2: 60, fn: +)

尾随闭包

如果将一个很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性
尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式

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

exec(v1: 10, v2: 20){
    $0 + $1
}

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

func exec(fn:(Int, Int) -> Int) {
    print(fn(1, 2))
}

exec(fn: {$0+$1})
exec(){$0+$1}
exec{$0+$1}

例:数组排序

//func sort(by areInIncreasingOrder: (Element, Element) -> Bool)

/// 返回true: i1排在i2前面
/// 返回false: i1排在i2后面
func cmp(i1: Int, i2: Int) -> Bool {
    // 大的排在前面
    return i1 > i2
}

var nums = [10, 30, 1, 30, 2, 45, 100 ,20, 60 ,15]

//nums.sort(by: cmp)
// [100, 60, 45, 30, 30, 20, 15, 10, 2, 1]


nums.sort(by: {
    (i1: Int, i2: Int) -> Bool in
    return i1 < i2
})
// [1, 2, 10, 15, 20, 30, 30, 45, 60, 100]

nums.sort(by: {i1, i2 in return i1 < i2})

nums.sort(by: {i1, i2 in i1 < i2})

nums.sort(by: {$0 < $1})

nums.sort(by: <)

nums.sort(){$0 < $1}

nums.sort{$0 < $1}

print(nums)

忽略参数

func exec(fn: (Int, Int) -> Int) {
   print(fn(1, 2))
}
exec { _,_ in 10 } // 10

闭包

定义:一个函数跟他锁捕获的常量/变量环境组合起来,称为闭包
a、一般指定义在函数内部的函数
b、一般它捕获的是外层函数的局部变量/常量

typealias Fn = (Int) -> Int
func getFn() -> Fn {
    var num = 0
    func plus(_ i:Int) -> Int{
        num += i
        return num
    }
    return plus
} // 返回的是plus和num形成的闭包

var fn1 = getFn()
print(fn1(1)) // 1
print(fn1(2)) // 3
print(fn1(3)) // 6

// 简写
func getFn() -> Fn{
    var num = 0
    return {
        num += i
        return num
    }
}

可以把闭包想象成是一个类的实例对象
内存在堆空间
捕获的局部变量/常量就是对象的成员(存储属性)
组成闭包的函数就是类内部定义的方法

class Closure {
    var num = 0
    func plus(_ i: Int) -> Int {
        num += i
        return num
    }
}
var cs1 = Closure()
var cs2 = Closure()
cs1.plus(1) // 1
cs2.plus(2) // 2
cs1.plus(3) // 4
cs2.plus(4) // 6
cs1.plus(5) // 9
cs2.plus(6) // 12

// 练习
var functions: [() -> Int] = []
for i in 1...3 {
    functions.append { i }
}
for f in functions {
       print(f())
}
                                      
// 1
// 2
// 3

class Closure {
    var i: Int
    init(_ i: Int) {
        self.i = i
    }
    func get() -> Int {
        return i
    }
}

var clses: [Closure] = []
for i in 1...3 {
    clses.append(Closure(i))
}
for cls in clses {
    print(cls.get())
}

*注意:如果返回的是函数类型,那么参数的修饰要保持统一

func add(_ num: Int) -> (inout Int) -> Void {
    func plus(v: inout Int) {
        v += num
    }
    return plus
}
var num = 5
add(20)(&num)
print(num)

自动闭包

为了避免与期望冲突,使用了@autoclosure的地方最好明确注释清楚:这个值会被推迟执行
@autoclosure 会自动将 20 封装成闭包 { 20 }
@autoclosure 只支持 () -> T 格式的参数
@autoclosure 并非只支持最后1个参数
空合并运算符 ?? 使用了 @autoclosure 技术
有@autoclosure、无@autoclosure,构成了函数重载

// 如果第1个数大于0,返回第一个数。否则返回第2个数
func getFirstPositive(_ v1: Int, _ v2: Int) -> Int {
    return v1 > 0 ? v1 : v2
}
getFirstPositive(10, 20) // 10
getFirstPositive(-2, 20) // 20
getFirstPositive(0, -4) // -4                             


// 改成函数类型的参数,可以让v2延迟加载
func getFirstPositive(_ v1: Int, _ v2: () -> Int) -> Int? {
    return v1 > 0 ? v1 : v2()
}
getFirstPositive(-4) { 20 }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SY.ZHOU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值