IOS开发语言Swift入门连载

IOS开发语言Swift入门连载—闭包

闭包是自包含的函数代码块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似。   闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift 会为您管理在捕获过程中涉及到的所有内存操作。   注意:   如果您不熟悉捕获(capturing)这个概念也不用担心,您可以在 值捕获 章节对其进行详细了解。   在函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一:   全局函数是一个有名字但不会捕获任何值的闭包   嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包   闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包   Swift的闭包表达式拥有简洁的风格,并鼓励在常见场景中进行语法优化,主要优化如下:   利用上下文推断参数和返回值类型   隐式返回单表达式闭包,即单表达式闭包可以省略return 关键字   参数名称缩写   尾随(Trailing)闭包语法   

闭包表达式(Closure Expressions)

  嵌套函数 是一个在较复杂函数中方便进行命名和定义自包含代码模块的方式。当然,有时候撰写小巧的没有完整定义和命名的类函数结构也是很有用处的,尤其是在您处理一些函数并需要将另外一些函数作为该函数的参数时。   闭包表达式是一种利用简洁语法构建内联闭包的方式。 闭包表达式提供了一些语法优化,使得撰写闭包变得简单明了。 下面闭包表达式的例子通过使用几次迭代展示了sort函数定义和语法优化的方式。 每一次迭代都用更简洁的方式描述了相同的功能。   

sort函数(The Sort Function)

  Swift标准库提供了sort 函数,会根据您提供的基于输出类型排序的闭包函数将已知类型数组中的值进行排序。 一旦排序完成,函数会返回一个与原数组大小相同的新数组,该数组中包含已经正确排序的同类型元素。  下面的闭包表达式示例使用sort 函数对一个String 类型的数组进行字母逆序排序,以下是初始数组值

let names = [“Chris”, “Alex”, “Ewa”, “Barry”, “Daniella”]

  sort 函数需要传入两个参数:  已知类型的数组   闭包函数,该闭包函数需要传入与数组类型相同的两个值,并返回一个布尔类型值来告诉sort函数当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回true ,反之返回false 。   该例子对一个String 类型的数组进行排序,因此排序闭包函数类型需为(String, String) -> Bool 。   提供排序闭包函数的一种方式是撰写一个符合其类型要求的普通函数,,并将其作为sort 函数的第二个参数传入:

func backwards(s1: String, s2: String) -> Bool {return s1 > s2}var reversed = sort(names, backwards)// reversed 为 [“Ewa”, “Daniella”, “Chris”, “Barry”, “Alex”]

  如果第一个字符串 (s1 ) 大于第二个字符串 (s2 ),backwards 函数返回true,表示在新的数组中s1 应该出现在s2 前。 对于字符串中的字符来说,“大于” 表示 “按照字母顺序较晚出现”。 这意味着字母”B” 大于字母”A” ,字符串”Tom” 大于字符串”Tim” 。 其将进行字母逆序排序,”Barry” 将会排在”Alex” 之后。   然而,这是一个相当冗长的方式,本质上只是写了一个单表达式函数 (a > b)。 在下面的例子中,利用闭合表达式语法可以更好的构造一个内联排序闭包。  

闭包表达式语法(Closure Expression Syntax)

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

{ (parameters) -> returnType instatements}

  闭包表达式语法可以使用常量、变量和inout 类型作为参数,不提供默认值。 也可以在参数列表的最后使用可变参数。 元组也可以作为参数和返回值。   下面的例子展示了之前backwards 函数对应的闭包表达式版本的代码:

reversed = sort(names, { (s1: String, s2: String) -> Bool inreturn s1 > s2})

  需要注意的是内联闭包参数和返回值类型声明与backwards 函数类型声明相同。 在这两种方式中,都写成了(s1: String, s2: String) -> Bool 。 然而在内联闭包表达式中,函数和返回值类型都写在大括号内,而不是大括号外。   闭包的函数体部分由关键字in 引入。 该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。   因为这个闭包的函数体部分如此短以至于可以将其改写成一行代码:

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

  这说明sort 函数的整体调用保持不变,一对圆括号仍然包裹住了函数中整个参数集合。而其中一个参数现在变成了内联闭包(相比于backwards 版本的代码)。  

根据上下文推断类型(Inferring Type From Context)

   因为排序闭包函数是作为sort 函数的参数进行传入的,Swift可以推断其参数和返回值的类型。 sort 期望第二个参数是类型为((String, String) -> Bool 的函数,因此实际上String ,String 和Bool 类型并不需要作为闭包表达式定义中的一部分。 因为所有的类型都可以被正确推断,返回箭头 (-> ) 和围绕在参数周围的括号也可以被省略:

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

  实际上任何情况下,通过内联闭包表达式构造的闭包作为参数传递给函数时,都可以推断出闭包的参数和返回值类型,这意味着您几乎不需要利用完整格式构造任何内联闭包。  

单表达式闭包隐式返回(Implicit Return From Single-Expression Clossures)

单行表达式闭包可以通过隐藏return 关键字来隐式返回单行表达式的结果,如上版本的例子可以改写为:

reversed = sort(names, { s1, s2 in s1 > s2 } )巨龟千岁,却也平淡无奇;昙花瞬间,却能绚丽无比。

IOS开发语言Swift入门连载

相关文章:

你感兴趣的文章:

标签云: