swift基础语法,19-闭包,闭包函数回调,尾随闭包,闭包捕获值

闭包:

函数是闭包的一种

类似于OC语言的block

闭包表达式(匿名函数) -- 能够捕获上下文中的值

语法: in关键字的目的是便于区分返回值和执行语句

闭包表达式的类型和函数的类型一样, 是参数加上返回值, 也就是in之前的部分

{

(参数) -> 返回值类型 in

执行语句

}

完整写法

let say:(String) -> Void = {

(name: String) -> Void in

print("hi \(name)")

}

say("qbs")

输出结果: hi qbs

没有返回值写法

let say:(String) ->Void = {

(name: String) in

print("hi \(name)")

}

say("qbs")

输出结果: hi qbs

没有参数没有返回值写法

let say:() ->Void = {

print("hi qbs")

}

say()

输出结果: hi qbs

闭包表达式作为回调函数

传统数组排序写法:

缺点: 不一定是小到大, 不一定是全部比较, 有可能只比较个位数

所以, 如何比较可以交给调用者决定

func bubbleSort(inout array:[Int])

{

let count = array.count;

for var i = 1; i < count; i++

{

for var j = 0; j < (count - i); j++

{

if array[j] > array[j + 1]

{

let temp = array[j]

array[j] = array[j + 1]

array[j + 1] = temp

}

}

}

}

闭包写法:

func bubbleSort(inout array:[Int], cmp: (Int, Int) -> Int)

{

let count = array.count;

for var i = 1; i < count; i++

{

for var j = 0; j < (count - i); j++

{

if cmp(array[j], array[j + 1]) == -1

{

let temp = array[j]

array[j] = array[j + 1]

array[j + 1] = temp

}

}

}

}

let cmp = {

(a: Int, b: Int) -> Int in

if a > b{

return 1;

}else if a < b

{

return -1;

}else

{

return 0;

}

}

var arr:Array<Int> = [31, 13, 52, 84, 5]

bubbleSort(&arr, cmp: cmp)

print(arr)

输出结果:

[84, 52, 31, 13, 5]

闭包作为参数传递

var arr:Array<Int> = [31, 13, 52, 84, 5]

bubbleSort(&arr, cmp: {

(a: Int, b: Int) -> Int in

if a > b{

return 1;

}else if a < b

{

return -1;

}else

{

return 0;

}

})

print(arr)

输出结果:

[84, 52, 31, 13, 5]

尾随闭包:

如果闭包是最后一个参数, 可以直接将闭包写到参数列表后面

这样可以提高阅读性. 称之为尾随闭包

bubbleSort(&arr) {

(a: Int, b: Int) -> Int in

if a > b{

return 1;

}else if a < b

{

return -1;

}else

{

return 0;

}

}

闭包表达式优化

1.类型优化, 由于函数中已经声明了闭包参数的类型

所以传入的实参可以不用写类型

2.返回值优化, 同理由于函数中已经声明了闭包的返回值类型

所以传入的实参可以不用写类型

3.参数优化, swift可以使用$索引的方式来访问闭包的参数, 默认从0开始

bubbleSort(&arr){

(a , b) -> Int in

(a , b) in

if $0 > $1{

return 1;

}else if $0 < $1

{

return -1;

}else

{

return 0;

}

}

如果只有一条语句可以省略return

let hehe = {

"我是qbs"

}

闭包捕获值

func getIncFunc() -> (Int) -> Int

{

var max = 10

func incFunc(x :Int) ->Int{

print("incFunc函数结束")

max++

return max + x

}

当执行到这一句时inc参数就应该被释放了

但是由于在内部函数中使用到了它, 所以它被捕获了

同理, 当执行完这一句时max变量就被释放了

但是由于在内部函数中使用到了它, 所以它被捕获了

print("getIncFunc函数结束")

return incFunc

}

被捕获的值会和与之对应的方法绑定在一起

同一个方法中的变量会被绑定到不同的方法中

let incFunc = getIncFunc()

print("---------")

print(incFunc(5))

print("---------")

print(incFunc(5))

输出结果:

getIncFunc函数结束

---------

incFunc函数结束

16

---------

incFunc函数结束

17

let incFunc2 = getIncFunc(5)

print(incFunc2(5))

输出结果:

getIncFunc函数结束

incFunc函数结束

16