Swift4.2 update chapter2 _07Closure

This commit is contained in:
Adolf
2018-11-06 11:15:56 +08:00
parent 8417b49bcd
commit 76b78304bd

View File

@ -1,14 +1,14 @@
# 闭包 # 闭包
*闭包*是自包含的函数代码块可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块blocks以及其他一些编程语言中的匿名函数比较相似。 *闭包*是自包含的函数代码块可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块blocks以及其他一些编程语言中的匿名函数Lambdas比较相似。
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。被称为*包裹*常量和变量。 Swift 会为你管理在捕获过程中涉及到的所有内存操作。 闭包可以捕获和存储其所在上下文中任意常量和变量的引用。被称为*包裹*常量和变量。 Swift 会为你管理在捕获过程中涉及到的所有内存操作。
> 注意 > 注意
> >
> 如果你不熟悉捕获capturing这个概念也不用担心你可以在[值捕获](#capturing_values)章节对其进行详细了解 > 如果你不熟悉捕获capturing这个概念也不用担心在[值捕获](#capturing_values)章节有它更详细的介绍
在[函数](./06_Functions.md)章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采如下三种形式之一: 在[函数](./06_Functions.md)章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采如下三种形式之一:
* 全局函数是一个有名字但不会捕获任何值的闭包 * 全局函数是一个有名字但不会捕获任何值的闭包
* 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 * 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
@ -24,14 +24,14 @@ Swift 的闭包表达式拥有简洁的风格,并鼓励在常见场景中进
<a name="closure_expressions"></a> <a name="closure_expressions"></a>
## 闭包表达式 ## 闭包表达式
[嵌套函数](./06_Functions.md#Nested_Functions)是一个在较复杂函数中方便进行命名和定义自包含代码模块的方式。当然,有时候编写小巧的没有完整定义和命名的类函数结构是很有用的,尤其是在你处理一些函数并需要将另外一些函数作为该函数的参数时。 [嵌套函数](./06_Functions.md#Nested_Functions)作为复杂函数的一部分时,它自包含代码块式的定义和命名形式在使用上带来了方便。当然,编写未完整声明和没有函数名的类函数结构代码是很有用的,尤其是在编码中涉及到函数作为参数的那些方法时。
*闭包表达式*是一种利用简洁语法构建内联闭包的方式。闭包表达式提供了一些语法优化,使得撰写闭包变得简单明了。下面闭包表达式的例子通过使用几次迭代展示了 `sorted(by:)` 方法定义和语法优化的方式。每一次迭代都用更简洁的方式描述了相同功能。 *闭包表达式*是一种构建内联闭包的方式,它的语法简洁。在保证不丢失它语法清晰明了的同时,闭包表达式提供了几种优化的语法简写形式。下面通过对 `sorted(by:)` 这一个案例的多次迭代改进来展示这个过程,每次迭代都使用了更加简明的方式描述了相同功能。
<a name="the_sorted_function"></a> <a name="the_sorted_function"></a>
### 排序方法 ### 排序方法
Swift 标准库提供了名为 `sorted(by:)` 的方法,它会根据你所提供的用于排序闭包函数将已知类型数组中的值进行排序。一旦排序完成`sorted(by:)` 方法会返回一个与数组大小相同,包含同类型元素且元素已正确排序的新数组。原数组不会被 `sorted(by:)` 方法修改。 Swift 标准库提供了名为 `sorted(by:)` 的方法,它会基于你提供的排序闭包表达式的判断结果对数组中的值(类型确定)进行排序。一旦它完成排序过程`sorted(by:)` 方法会返回一个与数组类型大小相同类型的新数组,该数组的元素有着正确排序顺序。原数组不会被 `sorted(by:)` 方法修改。
下面的闭包表达式示例使用 `sorted(by:)` 方法对一个 `String` 类型的数组进行字母逆序排序。以下是初始数组: 下面的闭包表达式示例使用 `sorted(by:)` 方法对一个 `String` 类型的数组进行字母逆序排序。以下是初始数组:
@ -104,7 +104,9 @@ reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
尽管如此,你仍然可以明确写出有着完整格式的闭包。如果完整格式的闭包能够提高代码的可读性,则我们更鼓励采用完整格式的闭包。而在 `sorted(by:)` 方法这个例子里,显然闭包的目的就是排序。由于这个闭包是为了处理字符串数组的排序,因此读者能够推测出这个闭包是用于字符串处理的。 尽管如此,你仍然可以明确写出有着完整格式的闭包。如果完整格式的闭包能够提高代码的可读性,则我们更鼓励采用完整格式的闭包。而在 `sorted(by:)` 方法这个例子里,显然闭包的目的就是排序。由于这个闭包是为了处理字符串数组的排序,因此读者能够推测出这个闭包是用于字符串处理的。
<a name="implicit_returns_from_single_expression_closures"></a> <a name="implicit_returns_from_single_expression_closures"></a>
### 单表达式闭包隐式返回
### 单表达式闭包的隐式返回
单行表达式闭包可以通过省略 `return` 关键字来隐式返回单行表达式的结果,如上版本的例子可以改写为: 单行表达式闭包可以通过省略 `return` 关键字来隐式返回单行表达式的结果,如上版本的例子可以改写为:
```swift ```swift
@ -129,7 +131,7 @@ reversedNames = names.sorted(by: { $0 > $1 } )
<a name="operator_methods"></a> <a name="operator_methods"></a>
### 运算符方法 ### 运算符方法
实际上还有一种更简短的方式来编写上面例子中的闭包表达式。Swift 的 `String` 类型定义了关于大于号(`>`)的字符串实现,其作为一个函数接受两个 `String` 类型的参数并返回 `Bool` 类型的值。而这正好与 `sorted(by:)` 方法的参数需要的函数类型相符合。因此你可以简单地传递一个大于号Swift 可以自动推断出你想使用大于号的字符串函数实现: 实际上还有一种更*简短的*方式来编写上面例子中的闭包表达式。Swift 的 `String` 类型定义了关于大于号(`>`)的字符串实现,其作为一个函数接受两个 `String` 类型的参数并返回 `Bool` 类型的值。而这正好与 `sorted(by:)` 方法的参数需要的函数类型相符合。因此你可以简单地传递一个大于号Swift 可以自动推断找到系统自带的那个字符串函数实现:
```swift ```swift
reversedNames = names.sorted(by: >) reversedNames = names.sorted(by: >)
@ -140,7 +142,7 @@ reversedNames = names.sorted(by: >)
<a name="trailing_closures"></a> <a name="trailing_closures"></a>
## 尾随闭包 ## 尾随闭包
如果你需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用*尾随闭包*来增强函数的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。在使用尾随闭包时,你不用写出它的参数标签: 如果你需要将一个很长的闭包表达式作为最后一个参数传递给函数,将这个闭包替换成为尾随闭包的形式很有用。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。在使用尾随闭包时,你不用写出它的参数标签:
```swift ```swift
func someFunctionThatTakesAClosure(closure: () -> Void) { func someFunctionThatTakesAClosure(closure: () -> Void) {
@ -158,7 +160,7 @@ someFunctionThatTakesAClosure() {
} }
``` ```
在[闭包表达式语法](#closure_expression_syntax)一节中作为 `sorted(by:)` 方法参数的字符串排序闭包可以改写为 在[闭包表达式语法](#closure_expression_syntax)上章节中的字符串排序闭包可以作为尾随包的形式改写在 `sorted(by:)` 方法圆括号的外面
```swift ```swift
reversedNames = names.sorted() { $0 > $1 } reversedNames = names.sorted() { $0 > $1 }