Swift笔记——闭包

每次看闭包的时候,都觉得挺简单的。不就是Objective-C中的block嘛,但是长时间不看,再来用的时候有些地方老是印象模糊,特别是一些省略写法。好记性不如烂笔头,还是决定整理整理记下来。

闭包描述排序方法

swift中有个排序的方法,它会根据你提供的闭包,对数组已知类型的元素进行排序。原数组:

因为这个数组的元素类型是字符串,所以需要传的闭包类型是写个这样类型的函数,并编译,就得出了排序之后的新数组了。

闭包语法

闭包的一般格式:

上面的例子可以闭包的形式替代:

闭包的内容是以开始的,标志着闭包的参数和返参已经定义完成,准备开始功能实现了。因为这个闭包的内容很少,所以甚至可以写成一行。

类型推断

因为闭包是作为一个参数传入一个方法,所以swift可以推断它参数的类型。上面的例子中,对一个元素为字符串的数组排序,所以传入的闭包类型必须为,这就意味着和类型不用写。因为所有的类型都可以推断,所以箭头和圆括号也可以删掉。当然如果继续写类型的话,在swift中是鼓励的,这样可以方便代码的读者阅读。

单行表达式的含蓄返回

如果闭包只有一句表达式,那么它会自动加上返回的功能,所以可以省略。

速写参数名

swift会自动对内联闭包提供速写参数名,比如、、等等。如果用这种方式的话,参数列表和也可以删掉。

算子

上面这个例子甚至还有一种更简单的方式,就是在闭包中直接传入一个大于的算子,swift可以推断你想要它针对字符串特定的实现。

尾随闭包

如果闭包是作为一个函数的最后一个参数传入,并且这个闭包很长,那么可以使用尾随闭包替代。尾随闭包是写在函数的调用括号外面,虽然它还是函数的一个参数。上面的例子就可以使用尾随闭包。

使用前:

使用后:

如果闭包是这个函数或方法的唯一参数,而且又是一个尾随闭包的话,那么连括号都可以删掉。

复杂一点的例子。用把一个类型的数组转化成类型的数组。

方法:

在这个闭包里,不用明确每个参数的类型是,因为闭包会自动推断。

捕捉变量

闭包可以捕获周围上下文中的常量和变量。现在有一个嵌套闭包。函数包含一个嵌套函数。嵌套函数捕获两个变量,和。通过捕获两个变量之后,每次调用函数,嵌套函数都会让加,并以闭包的形式作为函数的返参返回。

定义一个变量接收函数返回的闭包,并连续调用。

在函数里定义了一个变量用来储存累计增加的总数,初始化为0。调用返回来一个类型的闭包。第一次调时,为0,为10,调用后,返回10(0+10),同时变为10,以此类推。如果再调用一次函数生成一个新的闭包,并调用该闭包的话,那么该闭包捕获的的初始值仍然为0,这时候再重新调用,它的仍然为30,不受新生成的闭包的影响。

闭包是指针类型

定义一个常量指向闭包时,只是定义一个指向闭包的常量指针,而不是闭包本身是常量。比如上例中,如果定义另一个常量指向,它其实指向的是同一个闭包。

逃逸闭包

当一个闭包作为一个参数传入一个函数,并且这个闭包是在这个参数执行返回之后调用,那么这个闭包就是一个逃逸闭包,需要在参数类型前面用字段修饰,标明这个闭包可以逃逸,否则会报编译错误。

使用标记闭包,意味着你在闭包内部必须明确指向。

自动闭包

自动闭包用修饰,使用自动闭包可以延缓及时性要求不那么高的闭包的编译。但是使用自动闭包会增加代码的阅读难度。

Overusing autoclosures can make your code hard to understand. The context and function name should make it clear that evaluation is being deferred.

备注

Xcode版本:9.3.1

Swift版本:4.1

官方文档:Closures

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180614G1LO8D00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券