Swift学习笔记-优雅的闭包Closures

引言

一开始听说闭包Closures这个词是来自于Objective-C中的Block,乍一眼看起来特别像函数function,用着用着又有点像代理delegate。

官方对闭包的解释是自包含的函数代码块,可以在代码中传递和使用。OC中Closures经常用于函数回调,当然Swift中也同样,之所以第一篇Swift学习笔记就想介绍Closures,是因为它是在太神奇了,神奇到可以化繁为简,简化到看不懂代码!!!

Swift 的闭包表达式拥有简洁的风格,并鼓励在常见场景中进行语法优化,主要优化如下:

1.利用上下文推断参数和返回值类型

2.隐式返回单表达式闭包,即单表达式闭包可以省略return关键字

3.参数名称缩写

4.尾随(Trailing)闭包语法

因为Swift语言每次迭代的改动内容都较大,目前使用的代码版本是Swift2。


正文

本文将介绍一个简单的例子,对字符串数组的排序,这也是官方文档中的Demo。通过这个例子,大家会看到Swift是如何优雅地精简闭包表达式。

第一步:准备工作

(1)初始化一个字符串数组:

let names = ["Chris","Alex","Ewa","Barry","Daniella"]

(2)初始化一个对字符串排序函数

func backwards(s1:String, s2:String) ->Bool {

       returns1 > s2

}

backwards函数很简单。如果字符串s1大于字符串s2,backwards函数会返回true,表示在新的数组中s1出现在s2前。 对于字符串中的字符来说,“大于” 表示 “按照字母顺序较晚出现”。 这意味着字母"B"大于字母"A",字符串"Tom"大于字符串"Tim"。 其将进行字母逆序排序,"Barry"将会排在"Alex"之前。

第二步:对字符串数组进行排序

var reversed = names.sort(backwards)

sort函数会根据传入闭包函数的规则对names字符串数组进行排序,排序后names数组中的值为["Ewa", "Daniella", "Chris", "Barry", "Alex"],实现了对字符串数组的倒序排序。假如将backwards函数中的">"改为"<",那么排序的结果则是["Alex", "Barry", "Chris", "Daniella", "Ewa"],实现对字符串数组的顺序排序。


优化

上面这个简单的例子通过闭包函数实现了对字符串数组的排序,sort函数可以接受闭包函数作为参数进行计算。但是Swift可以更简单的方法来实现闭包函数,用闭包表达式。

闭包表达式语法有如下一般形式:

{ (parameters) -> Type in return statements}

parameters表示参数值,可以有一个或多个;Type表示返回类型; statements表示实现的规则;in和return是关键字。

在进行简化前,首先来复习下上面的字符串数组排序代码:

func backwards(s1:String, s2:String) ->Bool {

return s1 > s2

}

var reversed = names.sort(backwards)

如果用发功的功力来表示简化的程度,那么

三成功力-内联闭包表达式:

var reversed = names.sort({ (s1:String, s2:String) ->Bool in return s1 > s2})

{ (s1:String, s2:String) ->Bool in return s1 > s2}这个内联闭包表达式代替了原先backwards函数,关键字in表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。

五成功力-根据上下文推断类型:

var reversed = names.sort({ s1, s2 in return s1 > s2})

排序闭包表达式作为sort函数的参数进行传入,Swift可以推断其参数和返回值的类型。sort函数期望参数的类型为(String, String) -> Bool,因此实际上String,String和Bool类型并不需要作为闭包表达式定义中的一部分。 因为所有的类型都可以被正确推断,返回箭头 (->) 和围绕在参数周围的括号也可以被省略。实际上任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数时,都可以推断出闭包的参数和返回值类型,这意味着几乎不需要利用完整格式构造任何内联闭包。

六成功力-单表达式闭包隐式返回:

var reversed = names.sort({ s1, s2 in s1 > s2})

单行闭包表达式可以通过隐藏return关键字来隐式返回单行表达式的结果。

八成功力-参数名称缩写:

var reversed = names.sort({ $0 > $1 })

Swift 自动为内联函数提供了参数名称缩写功能,可以直接通过$0,$1,$2来顺序调用闭包的参数,$0表示第一个参数,$1表示第二个参数,以此类推。如果在闭包表达式中使用参数名称缩写,可以在闭包参数列表中省略对其的定义,并且对应参数名称缩写的类型会通过函数类型进行推断。in关键字也同样可以被省略,因为此时闭包表达式完全由闭包函数体构成。

十成功力-运算符函数:

var reversed = names.sort(>)

Swift 的String类型定义了关于大于号 (>) 的字符串实现,其作为一个函数接受两个String类型的参数并返回Bool类型的值。 而这正好与sort函数的参数需要的函数类型相符合。 因此,可以简单地传递一个大于号(>),Swift可以自动推断出使用大于号的字符串函数实现。


到目前为止,Swift已经完美的呈现了何为优雅。为了增强代码的可读性,Swift还添加了一项锦上添花的功能,尾随闭包,代码如下:

var reversed = names.sort(){ $0 > $1 }

闭包表达式尾随在sort函数的后面,使得代码更加的整洁优雅。


总结

Swift大法好,谁用谁知道!!!

你可能感兴趣的:(Swift学习笔记-优雅的闭包Closures)