闭包这个东西,一听就觉得逼格很高,本篇博客来讨论swift中的闭包。
闭包的定义是:巴拉巴拉,吼喽吼喽,OOXX。。。。。。,这就是闭包的定义。
其实,闭包就类似于其它语言中的lambda表达式,其本质就是一个匿名函数,作用有两个:
- 简化代码
- 装逼
本篇以数组的sortInPlace方法为切入点,一步一步地介绍闭包是如何简化代码(并装逼)的。
注:数组的sort方法返回一个排序好的新数组,原来的数组不发生变化,而sortInPlace方法是直接修改原来的数组。
不使用闭包
数组有一个sortInPlace()方法,可以将这个数组从小到大排列,例如:
var intArray=[8,2,4,3,6] intArray.sortInPlace()
此时数组为[2,6,8]
如果我希望将该数组从大到小排列,sortInPlace()方法还提供了一个重载的版本,sortInPlace(isOrderedBefore: (Int,Int) -> Bool),该重载的方法接受一个类型为(Int,Int) -> Bool的函数作为参数,sortInPlace会对数组中的任意两个值都调用该函数,返回true的放到前面,从而将该数组排序。
为了将数组从大到小排列,我可以定义一个函数,然后作为一个参数传递给sortInPlace方法
func compare(num1 :Int,num2 :Int)->Bool{
return num1 >= num2
}
intArray.sortInPlace(compare)
此时数组为[8,6]
,功能已经实现了。这是不使用闭包的方式。可见,闭包不是必须的。接着往下看,看看闭包能不能吸引你来使用它。
使用闭包表达式
我在上面已经提过了,闭包的本质就是匿名函数,接下来我们就使用闭包来调用sortInPlace方法
使用一般形式的闭包表达式
闭包表达式的一般形式是这样的:
{(parameter s) -> returnType in
statements
}
那么,下面就来用一般形式创建一个闭包并传递给sortInPlace方法
intArray.sortInPlace({(num1:Int,num2 :Int) ->Bool in return num1 >= num2 })
闭包的函数体部分由关键字 in引入。该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。
由于该闭包的函数体比较短,所以可以将其写在一行
intArray.sortInPlace({(num1:Int,num2 :Int) ->Bool in return num1 >= num2 })
简化参数类型和返回值类型
由于swift的类型推断机制,闭包可以省去参数的类型和返回值的类型,简化之后,代码如下:
intArray.sortInPlace({(num1,num2) in return num1 >= num2 })
单行表达式闭包可以省略return
如果闭包内的函数体只包含一行代码,就可以省略return关键字。简化之后,代码如下:
intArray.sortInPlace({(num1,num2) in num1 >= num2 })
参数名简写
Swift自动为内联函数提供了参数名称简写功能,我们可以直接通过 $0,$1,$2
等名字来引用闭包中的参数。简化之后,代码如下:
intArray.sortInPlace({$0 >= $1})
对于很多闭包来说,到这一步就已经是最精(zhuang)简(bi)的了,但对于本例中的闭包来说,还有更更精简的方式,就是直接使用swift提供的运算符函数。
运算符函数
swift中定义了>=这个运算符
public func >= (lhs: Int,rhs: Int) -> Bool
它的类型正好是我们的sortInPlace需要的类型,所以,我们可以将这个闭包简化为:
intArray.sortInPlace(>=)
Trailing 闭包
闭包还有一种形式,叫做Trailing闭包它的用途是:当一个很长的闭包作为一个函数的最后一个参数时,可以将该闭包写在参数所在的括号外面。如果我说的不是很明白,那么看代码
intArray.sortInPlace(){
return $0 >= $1
}
花括号在小括号外面,明白了吧。这样使用的话,闭包必须是函数的最后一个参数。
关于Trailing闭包,还有一点需要说明一下,如果Trailing闭包是某函数的唯一参数的话,那么调用该函数时,小括号也可以省略。简化以后,代码如下:
intArray.sortInPlace {
return $0 >= $1
}
关于闭包的使用就介绍到这里,闭包的语法非常灵活,语法糖也很甜,具体如何使用,就由你们自由发挥了!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。