{
+ case Empty
+ indirect case Node(value: T, left: Tree, right:Tree)
+}
+```
+
+要让一个枚举类型的所有用例都支持递归,使用 `indirect` 修饰符标记整个枚举类型,当枚举有多个用例且每个用例都需要使用 `indirect` 修饰符标记的时候这将非常便利。
+
+被 `indirect` 修饰符标记的枚举用例必须有一个关联值。使用 `indirect` 修饰符标记的枚举类型可以既包含有关联值的用例,同时还可包含没有关联值的用例。但是,它不能再单独使用 `indirect` 修饰符来标记某个用例。
+
+
+### 拥有原始值的枚举用例
+
+以下形式声明了一种枚举类型,其中各个枚举用例的类型均为同一种基本类型:
+
+```swift
+enum 枚举名称: 原始值类型, 采纳的协议 {
+ case 枚举用例1 = 原始值1
+ case 枚举用例2 = 原始值2
+}
+```
+
+在这种形式中,每一个用例块由 `case` 关键字开始,后面紧跟一个或多个以逗号分隔的枚举用例。和第一种形式的枚举用例不同,这种形式的枚举用例包含一个基础值,叫做原始值,各个枚举用例的原始值的类型必须相同。这些原始值的类型通过原始值类型指定,必须表示一个整数、浮点数、字符串或者字符。原始值类型必须符合 `Equatable` 协议和下列字面量转换协议中的一种:整型字面量需符合 `IntergerLiteralConvertible` 协议,浮点型字面量需符合 `FloatingPointLiteralConvertible` 协议,包含任意数量字符的字符串型字面量需符合 `StringLiteralConvertible` 协议,仅包含一个单一字符的字符串型字面量需符合 `ExtendedGraphemeClusterLiteralConvertible` 协议。每一个用例的名字和原始值必须唯一。
+
+如果原始值类型被指定为 `Int`,则不必为用例显式地指定原始值,它们会隐式地被赋值 `0`、`1`、`2` 等。每个未被赋值的 `Int` 类型的用例会被隐式地赋值,其值为上一个用例的原始值加 `1`。
+
+```Swift
+enum ExampleEnum: Int {
+ case A, B, C = 5, D
+}
+```
+
+在上面的例子中,`ExampleEnum.A` 的原始值是 `0`,`ExampleEnum.B` 的原始值是 `1`。因为 `ExampleEnum.C` 的原始值被显式地设定为 `5`,因此 `ExampleEnum.D` 的原始值会自动增长为 `6`。
+
+如果原始值类型被指定为 `String` 类型,你不用明确地为用例指定原始值,每个没有指定原始值的用例会隐式地将用例名字作为原始值。
+
+```swift
+enum WeekendDay: String {
+ case Saturday, Sunday
+}
+```
+
+在上面这个例子中,`WeekendDay.Saturday` 的原始值是 `"Saturday"`,`WeekendDay.Sunday` 的原始值是 `"Sunday"`。
+
+枚举用例具有原始值的枚举类型隐式地符合定义在 Swift 标准库中的 `RawRepresentable` 协议。所以,它们拥有一个 `rawValue` 属性和一个可失败构造器 `init?(rawValue: RawValue)`。可以使用 `rawValue` 属性去获取枚举用例的原始值,例如 `ExampleEnum.B.rawValue`。还可以根据原始值来创建一个相对应的枚举用例,只需调用枚举的可失败构造器,例如 `ExampleEnum(rawValue: 5)`,这个可失败构造器返回一个可选类型的用例。要获得更多关于具有原始值的枚举用例的信息和例子,请参阅 [原始值](../chapter2/08_Enumerations.md#raw_values)。
+
+
+### 访问枚举用例
+
+使用点语法(`.`)来引用枚举类型的枚举用例,例如 `EnumerationType.EnumerationCase`。当枚举类型可以由上下文推断而出时,可以省略它(但是 `.` 仍然需要),正如 [枚举语法](../chapter2/08_Enumerations.md#enumeration_syntax) 和 [显式成员表达式](04_Expressions.md#explicit_member_expression) 所述。
+
+可以使用 `switch` 语句来检验枚举用例的值,正如 [使用 switch 语句匹配枚举值](../chapter2/08_Enumerations.md#matching_enumeration_values_with_a_switch_statement) 所述。枚举类型是模式匹配的,依靠 `switch` 语句 `case` 块中的枚举用例模式,正如 [枚举用例模式](07_Patterns.md#enumeration_case_pattern) 所述。
+
+
+> 枚举声明语法
+
+
+> *枚举声明* → [*特性列表*](06_Attributes.md#attributes)可选 [*访问级别修饰符*](#access-level-modifier)可选 [*联合风格枚举*](#union-style-enum)
+> *枚举声明* → [*特性列表*](06_Attributes.md#attributes)可选 [*访问级别修饰符*](#access-level-modifier) 可选 [*原始值风格枚举*](#raw-value-style-enum)
+
+
+> *联合风格枚举* → **indirect**可选 **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [类型继承子句](03_Types.md#type-inheritance-clause)可选 **{** [*多个联合风格枚举成员*](#union-style-enum-members)可选 **}**
+>
+> *多个联合风格枚举成员* → [*联合风格枚举成员*](#union-style-enum-member) [*多个联合风格枚举成员*](#union-style-enum-members)可选
+>
+> *联合风格枚举成员* → [*声明*](#declaration) | [*联合风格枚举用例子句*](#union-style-enum-case-clause)
+>
+> *联合风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)可选 **indirect**可选 **case** [*联合风格枚举用例列表*](#union-style-enum-case-list)
+>
+> *联合风格枚举用例列表* → [*联合风格枚举用例*](#union-style-enum-case) | [*联合风格枚举用例*](#union-style-enum-case) **,** [*联合风格枚举用例列表*](#union-style-enum-case-list)
+>
+> *联合风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*元组类型*](03_Types.md#tuple-type)可选
+>
+> *枚举名称* → [*标识符*](02_Lexical_Structure.md#identifier)
+>
+> *枚举用例名称* → [*标识符*](02_Lexical_Structure.md#identifier)
+
+
+> *原始值风格枚举* → **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [类型继承子句](03_Types.md#type-inheritance-clause) **{** [*多个原始值风格枚举成员*](#raw-value-style-enum-members) **}**
+>
+> *多个原始值风格枚举成员* → [*原始值风格枚举成员*](#raw-value-style-enum-member) [*多个原始值风格枚举成员*](#raw-value-style-enum-members)可选
+>
+> *原始值风格枚举成员* → [*声明*](#declaration) | [*原始值风格枚举用例子句*](#raw-value-style-enum-case-clause)
+>
+> *原始值风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)可选 **case** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
+>
+> *原始值风格枚举用例列表* → [*原始值风格枚举用例*](#raw-value-style-enum-case) | [*原始值风格枚举用例*](#raw-value-style-enum-case) **,** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
+>
+> *原始值风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*原始值赋值*](#raw-value-assignment)可选
+>
+> *原始值赋值* → **=** [*原始值字面量*](#raw-value-literal)
+>
+> *原始值字面量* → [数字型字面量](02_Lexical_Structure.md#numeric-literal) | [字符串型字面量](02_Lexical_Structure.md#static-string-literal) | [布尔型字面量](02_Lexical_Structure.md#boolean-literal)
+
+
+## 结构体声明
+
+使用*结构体声明 (structure declaration)* 可以在程序中引入一个结构体类型。结构体声明使用 `struct` 关键字,遵循如下的形式:
+
+```swift
+struct 结构体名称: 采纳的协议 {
+ 多条声明
+}
+```
+
+结构体内可包含零个或多个声明。这些声明可以包括存储型和计算型属性、类型属性、实例方法、类型方法、构造器、下标、类型别名,甚至其他结构体、类、和枚举声明。结构体声明不能包含析构器或者协议声明。关于结构体的详细讨论和示例,请参阅 [类和结构体](../chapter2/09_Classes_and_Structures.md)。
+
+结构体可以采纳任意数量的协议,但是不能继承自类、枚举或者其他结构体。
+
+有三种方法可以创建一个已声明的结构体实例:
+
+* 调用结构体内声明的构造器,正如 [构造器](../chapter2/14_Initialization.md#initializers) 所述。
+
+* 如果没有声明构造器,调用结构体的成员逐一构造器,正如 [结构体类型的成员逐一构造器](../chapter2/14_Initialization.md#memberwise_initializers_for_structure_types) 所述。
+
+* 如果没有声明构造器,而且结构体的所有属性都有初始值,调用结构体的默认构造器,正如 [默认构造器](../chapter2/14_Initialization.md#default_initializers) 所述。
+
+结构体的构造过程请参阅 [构造过程](../chapter2/14_Initialization.md)。
+
+结构体实例的属性可以用点语法(`.`)来访问,正如 [访问属性](../chapter2/09_Classes_and_Structures.md#accessing_properties) 所述。
+
+结构体是值类型。结构体的实例在被赋予变量或常量,或传递给函数作为参数时会被复制。关于值类型的更多信息,请参阅
+[结构体和枚举是值类型](../chapter2/09_Classes_and_Structures.md#structures_and_enumerations_are_value_types)。
+
+可以使用扩展声明来扩展结构体类型的行为,请参阅 [扩展声明](#extension_declaration)。
+
+
+> 结构体声明语法
+>
+> *结构体声明* → [*特性列表*](06_Attributes.md#attributes)可选 [*访问级别修饰符*](#access-level-modifier) 可选 **struct** [*结构体名称*](#struct-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [类型继承子句](03_Types.md#type-inheritance-clause)可选 [*结构体主体*](#struct-body)
+>
+> *结构体名称* → [*标识符*](02_Lexical_Structure.md#identifier)
+>
+> *结构体主体* → **{** [*多条声明*](#declarations)可选 **}**
+
+
+## 类声明
+
+可以在程序中使用*类声明 (class declaration)* 来引入一个类。类声明使用关键字 `class`,遵循如下的形式:
+
+```swift
+class 类名: 超类, 采纳的协议 {
+ 多条声明
+}
+```
+
+类内可以包含零个或多个声明。这些声明可以包括存储型和计算型属性、实例方法、类型方法、构造器、唯一的析构器、下标、类型别名,甚至其他结构体、类和枚举声明。类声明不能包含协议声明。关于类的详细讨论和示例,请参阅 [类和结构体](../chapter2/09_Classes_and_Structures.md)。
+
+一个类只能继承自一个超类,但是可以采纳任意数量的协议。超类紧跟在类名和冒号后面,其后跟着采纳的协议。泛型类可以继承自其它泛型类和非泛型类,但是非泛型类只能继承自其它非泛型类。当在冒号后面写泛型超类的名称时,必须写上泛型类的全名,包括它的泛型形参子句。
+
+正如 [构造器声明](#initializer_declaration) 所讨论的,类可以有指定构造器和便利构造器。类的指定构造器必须初始化类中声明的所有属性,并且必须在调用超类构造器之前。
+
+类可以重写属性、方法、下标以及构造器。重写的属性、方法、下标和指定构造器必须以 `override` 声明修饰符标记。
+
+为了要求子类去实现超类的构造器,使用 `required` 声明修饰符标记超类的构造器。子类实现超类构造器时也必须使用 `required` 声明修饰符。
+
+虽然超类属性和方法声明可以被当前类继承,但是超类声明的指定构造器却不能。即便如此,如果当前类重写了超类的所有指定构造器,它就会继承超类的所有便利构造器。Swift 的类并不继承自一个通用基础类。
+
+有两种方法来创建已声明的类的实例:
+
+* 调用类中声明的构造器,请参阅 [构造器](../chapter2/14_Initialization.md#initializers)。
+
+* 如果没有声明构造器,而且类的所有属性都被赋予了初始值,调用类的默认构造器,请参阅 [默认构造器](../chapter2/14_Initialization.md#default_initializers)。
+
+类实例属性可以用点语法(`.`)来访问,请参阅 [访问属性](../chapter2/09_Classes_and_Structures.md#accessing_properties)。
+
+类是引用类型。当被赋予常量或变量,或者传递给函数作为参数时,类的实例会被引用,而不是被复制。关于引用类型的更多信息,请参阅 [结构体和枚举是值类型](../chapter2/09_Classes_and_Structures.md#structures_and_enumerations_are_value_types)。
+
+可以使用扩展声明来扩展类的行为,请参阅 [扩展声明](#extension_declaration)。
+
+
+> 类声明语法
+>
+> *类声明* → [*特性列表*](06_Attributes.md#attributes)可选 [访问级别修饰符](#access-level-modifier)可选 **class** [*类名*](#class-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*类型继承子句*](03_Types.md#type-inheritance-clause)可选 [*类主体*](#class-body)
+>
+> *类名* → [*标识符*](02_Lexical_Structure.md#identifier)
+>
+> *类主体* → **{** [*多条声明*](#declarations)可选 **}**
+
+
+## 协议声明
+
+*协议声明 (protocol declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
+
+```swift
+protocol 协议名称: 继承的协议 {
+ 协议成员声明
+}
+```
+
+协议的主体包含零个或多个协议成员声明,这些成员描述了任何采纳该协议的类型必须满足的一致性要求。一个协议可以声明采纳者必须实现的某些属性、方法、构造器以及下标。协议也可以声明各种各样的类型别名,叫做关联类型,它可以指定协议的不同声明之间的关系。协议声明不能包括类、结构体、枚举或者其它协议的声明。协议成员声明会在后面进行讨论。
+
+协议类型可以继承自任意数量的其它协议。当一个协议类型继承自其它协议的时候,来自其它协议的所有要求会聚合在一起,而且采纳当前协议的类型必须符合所有的这些要求。关于如何使用协议继承的例子,请参阅 [协议继承](../chapter2/22_Protocols.md#protocol_inheritance)。
+
+> 注意
+> 也可以使用协议合成类型来聚合多个协议的一致性要求,请参阅 [协议合成类型](03_Types.md#protocol_composition_type) 和 [协议合成](../chapter2/22_Protocols.md#protocol_composition)。
+
+可以通过类型的扩展声明来采纳协议,从而为之前声明的类型添加协议一致性。在扩展中,必须实现所有采纳协议的要求。如果该类型已经实现了所有的要求,可以让这个扩展声明的主体留空。
+
+默认地,符合某个协议的类型必须实现所有在协议中声明的属性、方法和下标。即便如此,可以用 `optional` 声明修饰符标注协议成员声明,以指定它们的实现是可选的。`optional` 修饰符仅仅可以用于使用 `objc` 特性标记过的协议。因此,仅仅类类型可以采用并符合包含可选成员要求的协议。更多关于如何使用 `optional` 声明修饰符的信息,以及如何访问可选协议成员的指导——例如不能确定采纳协议的类型是否实现了它们时——请参阅 [可选协议要求](../chapter2/22_Protocols.md#optional_protocol_requirements)
+
+为了限制协议只能被类类型采纳,需要使用 `class` 关键字来标记协议,将 `class` 关键在写在冒号后面的继承的协议列表的首位。例如,下面的协议只能被类类型采纳:
+
+```swift
+protocol SomeProtocol: class {
+ /* 这里是协议成员 */
+}
+```
+
+任何继承自标记有 `class` 关键字的协议的协议也仅能被类类型采纳。
+
+> 注意
+> 如果协议已经用 `objc` 特性标记了,`class` 要求就隐式地应用于该协议,无需显式使用 `class` 关键字。
+
+协议类型是命名的类型,因此它们可以像其他命名类型一样使用,正如 [协议作为类型](../chapter2/22_Protocols.md#protocols_as_types) 所讨论的。然而,不能构造一个协议的实例,因为协议实际上不提供它们指定的要求的实现。
+
+可以使用协议来声明作为代理的类或者结构体应该实现的方法,正如 [委托(代理)模式](../chapter2/22_Protocols.md#delegation) 中所述。
+
+
+> 协议声明语法
+
+
+> *协议声明* → [*特性列表*](06_Attributes.md#attributes)可选 [访问级别修饰符](#access-level-modifier)可选 **protocol** [*协议名称*](#protocol-name) [*类型继承子句*](03_Types.html#type-inheritance-clause)可选 [*协议主体*](#protocol-body)
+>
+> *协议名称* → [*标识符*](02_Lexical_Structure.md#identifier)
+>
+> *协议主体* → **{** [*协议成员声明列表*](#protocol-member-declarations)可选 **}**
+
+
+> *协议成员声明* → [*协议属性声明*](#protocol-property-declaration)
+> *协议成员声明* → [*协议方法声明*](#protocol-method-declaration)
+> *协议成员声明* → [*协议构造器声明*](#protocol-initializer-declaration)
+> *协议成员声明* → [*协议下标声明*](#protocol-subscript-declaration)
+> *协议成员声明* → [*协议关联类型声明*](#protocol-associated-type-declaration)
+>
+> *协议成员声明列表* → [*协议成员声明*](#protocol-member-declaration) [*协议成员声明列表*](#protocol-member-declarations)可选
+
+
+### 协议属性声明
+
+协议可以通过在协议声明主体中引入一个协议属性声明,来声明符合的类型必须实现的属性。协议属性声明有一种特殊的变量声明形式:
+
+```swift
+var 属性名: 类型 { get set }
+```
+
+同其它协议成员声明一样,这些属性声明仅仅针对符合该协议的类型声明了 getter 和 setter 要求,你不能在协议中直接实现 getter 和 setter。
+
+符合类型可以通过多种方式满足 getter 和 setter 要求。如果属性声明包含 `get` 和 `set` 关键字,符合类型就可以用存储型变量属性或可读可写的计算型属性来满足此要求,但是属性不能以常量属性或只读计算型属性实现。如果属性声明仅仅包含 `get` 关键字的话,它可以作为任意类型的属性被实现。关于如何实现协议中的属性要求的例子,请参阅 [属性要求](../chapter2/22_Protocols.md#property_requirements)
+
+另请参阅 [变量声明](#variable_declaration)。
+
+
+> 协议属性声明语法
+>
+> *协议属性声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
+
+
+### 协议方法声明
+
+协议可以通过在协议声明主体中引入一个协议方法声明,来声明符合的类型必须实现的方法。协议方法声明和函数方法声明有着相同的形式,但有两项例外:它们不包括函数体,也不能包含默认参数。关于如何实现协议中的方法要求的例子,请参阅 [方法要求](../chapter2/22_Protocols.md#method_requirements)。
+
+使用 `static` 声明修饰符可以在协议声明中声明一个类型方法。结构体实现这些方法时使用 `static` 声明修饰符,类在实现这些方法时,除了使用 `static` 声明修饰符,还可以选择使用 `class` 声明修饰符。通过扩展实现时亦是如此。
+
+另请参阅 [函数声明](#function_declaration)。
+
+
+> 协议方法声明语法
+>
+> *协议方法声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*函数签名*](#function-signature)
+
+
+### 协议构造器声明
+
+协议可以通过在协议声明主体中引入一个协议构造器声明,来声明符合的类型必须实现的构造器。协议构造器声明
+除了不包含实现主体外,和构造器声明有着相同的形式。
+
+符合类型可以通过实现一个非可失败构造器或者 `init!` 可失败构造器来满足一个非可失败协议构造器的要求,可以通过实现任意类型的构造器来满足一个可失败协议构造器的要求。
+
+类在实现一个构造器去满足一个协议的构造器要求时,如果这个类还没有用 `final` 声明修饰符标记,这个构造器必须用 `required` 声明修饰符标记。
+
+另请参阅 [构造器声明](#initializer_declaration)。
+
+
+> 协议构造器声明语法
+>
+> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*参数子句*](#parameter-clause) **throws**可选
+> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*参数子句*](#parameter-clause) **rethrows**
+
+
+### 协议下标声明
+
+协议可以通过在协议声明主体中引入一个协议下标声明,来声明符合的类型必须实现的下标。协议下标声明有一个特殊的下标声明形式:
+
+```swift
+subscript (参数列表) -> 返回类型 { get set }
+```
+
+下标声明只为符合类型声明了 getter 和 setter 要求。如果下标声明包含 `get` 和 `set` 关键字,符合类型也必须实现 getter 和 setter 子句。如果下标声明只包含 `get` 关键字,符合类型必须实现 getter 子句,可以选择是否实现 setter 子句。
+
+另请参阅 [下标声明](#subscript_declaration)。
+
+
+> 协议下标声明语法
+>
+> *协议下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
+
+
+### 协议关联类型声明
+
+使用关键字 `associatedtype` 来声明协议关联类型。关联类型为作为协议声明的一部分,为某种类型提供了一个别名。关联类型和泛型参数子句中的类型参数很相似,但是它们和 `Self` 一样,用于协议中。`Self` 指代采纳协议的类型。要获得更多信息和例子,请参阅 [关联类型](../chapter2/23_Generics.md#associated_types)。
+
+另请参阅 [类型别名声明](#type_alias_declaration)。
+
+
+> 协议关联类型声明语法
+>
+> *协议关联类型声明* → [*类型别名头*](#typealias-head) [*类型继承子句*](03_Types.md#type-inheritance-clause)可选 [*类型别名赋值*](#typealias-assignment)可选
+
+
+## 构造器声明
+
+构造器声明会为程序中的类、结构体或枚举引入构造器。构造器使用关键字 `init` 来声明,有两种基本形式。
+
+结构体、枚举、类可以有任意数量的构造器,但是类的构造器具有不同的规则和行为。不同于结构体和枚举,类有两种构造器,即指定构造器和便利构造器,请参阅 [构造过程](../chapter2/14_Initialization.md)。
+
+采用如下形式声明结构体和枚举的构造器,以及类的指定构造器:
+
+```swift
+init(参数列表) {
+ 构造语句
+}
+```
+
+类的指定构造器直接将类的所有属性初始化。它不能调用类中的其他构造器,如果类有超类,则必须调用超类的一个指定构造器。如果该类从它的超类继承了属性,必须在调用超类的指定构造器后才能修改这些属性。
+
+指定构造器只能在类声明中声明,不能在扩展声明中声明。
+
+结构体和枚举的构造器可以调用其他已声明的构造器,从而委托其他构造器来进行部分或者全部构造过程。
+
+要为类声明一个便利构造器,用 `convenience` 声明修饰符来标记构造器声明:
+
+```swift
+convenience init(参数列表) {
+ 构造语句
+}
+```
+
+便利构造器可以将构造过程委托给另一个便利构造器或一个指定构造器。但是,类的构造过程必须以一个将类中所有属性完全初始化的指定构造器的调用作为结束。便利构造器不能调用超类的构造器。
+
+可以使用 `required` 声明修饰符,将便利构造器和指定构造器标记为每个子类都必须实现的构造器。这种构造器的子类实现也必须使用 `required` 声明修饰符标记。
+
+默认情况下,超类中的构造器不会被子类继承。但是,如果子类的所有存储型属性都有默认值,而且子类自身没有定义任何构造器,它将继承超类的构造器。如果子类重写了超类的所有指定构造器,子类将继承超类的所有便利构造器。
+
+和方法、属性和下标一样,需要使用 `override` 声明修饰符标记重写的指定构造器。
+
+> 注意
+> 如果使用 `required` 声明修饰符标记一个构造器,在子类中重写这种构造器时,无需使用 `override` 修饰符。
+
+就像函数和方法,构造器也可以抛出或者重抛错误,你可以在构造器参数列表的圆括号之后使用 `throws` 或 `rethrows` 关键字来表明相应的抛出行为。
+
+关于在不同类型中声明构造器的例子,请参阅 [构造过程](../chapter2/14_Initialization.md)。
+
+
+### 可失败构造器
+
+可失败构造器可以生成所属类型的可选实例或者隐式解包可选实例,因此,这种构造器通过返回 `nil` 来指明构造过程失败。
+
+声明生成可选实例的可失败构造器时,在构造器声明的 `init` 关键字后加追加一个问号(`init?`)。声明生成隐式解包可选实例的可失败构造器时,在构造器声明后追加一个叹号(`init!`)。使用 `init?` 可失败构造器生成结构体的一个可选实例的例子如下。
+
+```swift
+struct SomeStruct {
+ let string: String
+ //生成一个 SomeStruct 的可选实例
+ init?(input: String) {
+ if input.isEmpty {
+ // 丢弃 self,并返回 nil
+ return nil
+ }
+ string = input
+ }
+}
+```
+
+调用 `init?` 可失败构造器和调用非可失败构造器的方式相同,不过你需要处理可选类型的返回值。
+
+```swift
+if let actualInstance = SomeStruct(input: "Hello") {
+ // 利用 SomeStruct 实例做些事情
+} else {
+ // SomeStruct 实例的构造过程失败,构造器返回了 nil
+}
+```
+
+可失败构造器可以在构造器实现中的任意位置返回 `nil`。
+
+可失败构造器可以委托任意种类的构造器。非可失败可以委托其它非可失败构造器或者 `init!` 可失败构造器。非可失败构造器可以委托超类的 `init?` 可失败指定构造器,但是需要使用强制解包,例如 `super.init()!`。
+
+构造过程失败通过构造器委托来传递。具体来说,如果可失败构造器委托的可失败构造器构造过程失败并返回 `nil`,那么该可失败构造器也会构造失败并隐式地返回 `nil`。如果非可失败构造器委托的 `init!` 可失败构造器构造失败并返回了 `nil`,那么会发生运行时错误(如同使用 `!` 操作符去强制解包一个值为 `nil` 的可选值)。
+
+子类可以用任意种类的指定构造器重写超类的可失败指定构造器,但是只能用非可失败指定构造器重写超类的非可失败指定构造器。
+
+更多关于可失败构造器的信息和例子,请参阅 [可失败构造器](../chapter2/14_Initialization.md#failable_initializers)。
+
+
+> 构造器声明语法
+>
+> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*参数子句*](#parameter-clause) **throws**可选 [*构造器主体*](#initializer-body)
+> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)可选 [*参数子句*](#parameter-clause) **rethrows**可选 [*构造器主体*](#initializer-body)
+>
+> *构造器头* → [*特性列表*](06_Attributes.md#attributes)可选 [*声明修饰符列表*](#declaration-modifiers)可选 **init**
+> *构造器头* → [*特性列表*](06_Attributes.md#attributes)可选 [*声明修饰符列表*](#declaration-modifiers)可选 **init** **?**
+> *构造器头* → [*特性列表*](06_Attributes.md#attributes)可选 [*声明修饰符列表*](#declaration-modifiers)可选 **init** **!**
+>
+> *构造器主体* → [*代码块*](#code-block)
+
+
+## 析构器声明
+
+*析构器声明 (deinitializer declaration)* 可以为类声明一个析构器。析构器没有参数,遵循如下格式:
+
+```swift
+deinit {
+ 语句
+}
+```
+
+当没有任何强引用引用着类的对象,对象即将被释放时,析构器会被自动调用。析构器只能在类主体的声明中声明,不能在类的扩展声明中声明,并且每个类最多只能有一个析构器。
+
+子类会继承超类的析构器,并会在子类对象将要被释放时隐式调用。继承链上的所有析构器全部调用完毕后子类对象才会被释放。
+
+析构器不能直接调用。
+
+关于如何在类声明中使用析构器的例子,请参阅 [析构过程](../chapter2/15_Deinitialization.md)。
+
+
+> 析构器声明语法
+>
+> *析构器声明* → [*特性列表*](06_Attributes.md#attributes)可选 **deinit** [*代码块*](#code-block)
+
+
+## 扩展声明
+
+*扩展声明 (extension declaration)* 可以扩展一个现存的类、结构体和枚举类型的行为。扩展声明使用关键字 `extension`,遵循如下格式:
+
+```swift
+extension 类型名称: 采纳的协议 {
+ 声明语句
+}
+```
+
+扩展声明体可包含零个或多个声明语句。这些声明语句可以包括计算型属性、计算型类型属性、实例方法、类型方法、构造器、下标声明,甚至其他结构体、类和枚举声明。扩展声明不能包含析构器、协议声明、存储型属性、属性观察器或其他扩展声明。关于扩展声明的详细讨论,以及各种扩展声明的例子,请参阅 [扩展](../chapter2/21_Extensions.md)。
+
+扩展声明可以为现存的类、结构体、枚举添加协议一致性,但是不能为类添加超类,因此在扩展声明的类型名称的冒号后面仅能指定一个协议列表。
+
+现存类型的属性、方法、构造器不能在扩展中被重写。
+
+扩展声明可以包含构造器声明。这意味着,如果被扩展的类型在其他模块中定义,构造器声明必须委托另一个在那个模块中声明的构造器,以确保该类型能被正确地初始化。
+
+
+> 扩展声明语法
+>
+> *扩展声明* → [访问级别修饰符](#access-level-modifier)可选 **extension** [*类型标识符*](03_Types.md#type-identifier) [*类型继承子句*](03_Types.md#type-inheritance-clause)可选 [*扩展主体*](#extension-body)
+>
+> *扩展主体* → **{** [*多条声明*](#declarations)可选 **}**
+
+
+## 下标声明
+
+*下标声明 (subscript declaration)* 用于为特定类型的对象添加下标支持,通常也用于为访问集合、列表和序列中的元素提供语法便利。下标声明使用关键字 `subscript`,形式如下:
+
+```swift
+subscript (参数列表) -> 返回类型 {
+ get {
+ 语句
+ }
+ set(setter 名称) {
+ 语句
+ }
+}
+```
+
+下标声明只能出现在类、结构体、枚举、扩展和协议的声明中。
+
+参数列表指定一个或多个用于在相关类型的下标表达式中访问元素的索引(例如,表达式 `object[i]` 中的 `i`)。索引可以是任意类型,但是必须包含类型标注。返回类型指定了被访问的元素的类型。
+
+和计算型属性一样,下标声明支持对元素的读写操作。getter 用于读取值,setter 用于写入值。setter 子句是可选的,当仅需要一个 getter 子句时,可以将二者都忽略,直接返回请求的值即可。但是,如果提供了 setter 子句,就必须提供 getter 子句。
+
+圆括号以及其中的 setter 名称是可选的。如果提供了 setter 名称,它会作为 setter 的参数名称。如果不提供 setter 名称,那么 setter 的参数名称默认是 `value`。setter 名称的类型必须与返回类型相同。
+
+可以重载下标,只要参数列表或返回类型不同即可。还可以重写继承自超类的下标,此时必须使用 `override` 声明修饰符声明被重写的下标。
+
+同样可以在协议声明中声明下标,正如 [协议下标声明](#protocol_subscript_declaration) 中所述。
+
+更多关于下标的信息和例子,请参阅 [下标](../chapter2/12_Subscripts.md)。
+
+
+> 下标声明语法
+>
+> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*代码块*](#code-block)
+> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter代码块*](#getter-setter-block)
+> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
+>
+> *下标头* → [*特性列表*](06_Attributes.md#attributes)可选 [*声明修饰符列表*](#declaration-modifiers)可选 **subscript** [*参数子句*](#parameter-clause)
+>
+> *下标结果* → **->** [*特性列表*](06_Attributes.md#attributes)可选 [*类型*](03_Types.md#type)
+
+
+## 运算符声明
+
+*运算符声明 (operator declaration)* 会向程序中引入中缀、前缀或后缀运算符,使用关键字 `operator` 来声明。
+
+可以声明三种不同的缀性:中缀、前缀和后缀。运算符的缀性指定了运算符与其运算对象的相对位置。
+
+运算符声明有三种基本形式,每种缀性各一种。运算符的缀性通过在 `operator` 关键字之前添加声明修饰符 `infix`,`prefix` 或 `postfix` 来指定。每种形式中,运算符的名字只能包含 [运算符](02_Lexical_Structure.md#operators) 中定义的运算符字符。
+
+下面的形式声明了一个新的中缀运算符:
+
+```swift
+infix operator 运算符名称 {
+ precedence 优先级
+ associativity 结合性
+}
+```
+
+中缀运算符是二元运算符,置于两个运算对象之间,例如加法运算符(`+`)位于表达式 `1 + 2` 的中间。
+
+中缀运算符可以选择指定优先级或结合性,或者两者同时指定。
+
+运算符的优先级可以指定在没有括号包围的情况下,运算符与其运算对象如何结合。可以使用上下文相关的关键字 `precedence` 以及紧随其后的优先级数字来指定一个运算符的优先级。优先级可以是 `0` 到 `255` 之间的任何十进制整数。与十进制整数字面量不同的是,它不可以包含任何下划线字符。尽管优先级是一个特定的数字,但它仅用作与另一个运算符的优先级比较大小。也就是说,当两个运算符为同一个运算对象竞争时,例如 `2 + 3 * 5`,优先级更高的运算符将优先参与运算。
+
+运算符的结合性可以指定在没有括号包围的情况下,多个优先级相同的运算符将如何组合。可以使用上下文相关的关键字 `associativity` 以及紧随其后的结合性关键字来指定运算符的结合性,结合性关键字也是上下文相关的,包括 `left`、`right` 和 `none`。左结合运算符以从左到右的顺序进行组合。例如,减法运算符(`-`)具有左结合性,因此 `4 - 5 - 6` 以 `(4 - 5) - 6` 的形式组合,其结果为 `-7`。右结合运算符以从右到左的顺序组合,而设置为 `none` 的运算符不进行组合。具有相同优先级的非结合运算符,不可以互相邻接。例如,表达式 `1 < 2 < 3` 是非法的。
+
+声明时不指定任何优先级或结合性的中缀运算符,优先级为 `100`,结合性为 `none`。
+
+下面的形式声明了一个新的前缀运算符:
+
+```swift
+prefix operator 运算符名称 {}
+```
+
+出现在运算对象前边的前缀运算符是一元运算符,例如表达式 `!a` 中的前缀非运算符(`!`)。
+
+前缀运算符的声明中不指定优先级,而且前缀运算符是非结合的。
+
+下面的形式声明了一个新的后缀运算符:
+
+```swift
+postfix operator 运算符名称 {}
+```
+
+紧跟在运算对象后边的后缀运算符是一元运算符,例如表达式 `a!` 中的后缀强制解包运算符(`!`)。
+
+和前缀运算符一样,后缀运算符的声明中不指定优先级,而且后缀运算符是非结合的。
+
+声明了一个新的运算符以后,需要实现一个跟这个运算符同名的函数来实现这个运算符。如果是实现一个前缀或者后缀运算符,也必须使用相符的 `prefix` 或者 `postfix` 声明修饰符标记函数声明。如果是实现中缀运算符,则不需要使用 `infix` 声明修饰符标记函数声明。关于如何实现一个新的运算符的例子,请参阅 [自定义运算符](../chapter2/25_Advanced_Operators.md#custom_operators)。
+
+
+> 运算符声明语法
+
+
+> *运算符声明* → [*前缀运算符声明*](#prefix-operator-declaration) | [*后缀运算符声明*](#postfix-operator-declaration) | [*中缀运算符声明*](#infix-operator-declaration)
+
+
+> *前缀运算符声明* → **prefix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
+>
+> *后缀运算符声明* → **postfix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
+>
+> *中缀运算符声明* → **infix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** [*中缀运算符属性*](#infix-operator-attributes)可选 **}**
+
+
+> *中缀运算符属性* → [*优先级子句*](#precedence-clause)可选 [*结和性子句*](#associativity-clause)可选
+>
+> *优先级子句* → **precedence** [*优先级水平*](#precedence-level)
+>
+> *优先级水平* → 十进制整数 0 到 255,包含 0 和 255
+>
+> *结和性子句* → **associativity** [*结和性*](#associativity)
+>
+> *结和性* → **left** | **right** | **none**
+
+
+## 声明修饰符
+
+声明修饰符都是关键字或上下文相关的关键字,可以修改一个声明的行为或者含义。可以在声明的特性(如果存在)和引入该声明的关键字之间,利用声明修饰符的关键字或上下文相关的关键字指定一个声明修饰符。
+
+`dynamic`
+
+该修饰符用于修饰任何兼容 Objective-C 的类的成员。访问被 `dynamic` 修饰符标记的类成员将总是由 Objective-C 运行时系统进行动态派发,而不会由编译器进行内联或消虚拟化。
+
+因为被标记 `dynamic` 修饰符的类成员会由 Objective-C 运行时系统进行动态派发,所以它们会被隐式标记 `objc` 特性。
+
+`final`
+
+该修饰符用于修饰类或类中的属性、方法以及下标。如果用它修饰一个类,那么这个类不能被继承。如果用它修饰类中的属性、方法或下标,那么它们不能在子类中被重写。
+
+`lazy`
+
+该修饰符用于修饰类或结构体中的存储型变量属性,表示该属性的初始值最多只被计算和存储一次,且发生在它被第一次访问时。关于如何使用 `lazy` 修饰符的例子,请参阅 [惰性存储型属性](../chapter2/10_Properties.md#lazy_stored_properties)。
+
+`optional`
+
+该修饰符用于修饰协议中的属性、方法以及下标成员,表示符合类型可以不实现这些成员要求。
+
+只能将 `optional` 修饰符用于被 `objc` 特性标记的协议。这样一来,就只有类类型可以采纳并符合拥有可选成员要求的协议。关于如何使用 `optional` 修饰符,以及如何访问可选协议成员(比如,不确定符合类型是否已经实现了这些可选成员)的信息,请参阅 [可选协议要求](../chapter2/22_Protocols.md#optional_protocol_requirements)。
+
+`required`
+
+该修饰符用于修饰类的指定构造器或便利构造器,表示该类所有的子类都必须实现该构造器。在子类实现该构造器时,必须同样使用 `required` 修饰符修饰该构造器。
+
+`weak`
+
+该修饰符用于修饰变量或存储型变量属性,表示该变量或属性持有其存储的对象的弱引用。这种变量或属性的类型必须是可选的类类型。使用 `weak` 修饰符可避免强引用循环。关于 `weak` 修饰符的更多信息和例子,请参阅 [弱引用](../chapter2/16_Automatic_Reference_Counting.md#resolving_strong_reference_cycles_between_class_instances)。
+
+
+### 访问控制级别
+
+Swift 提供了三个级别的访问控制:`public`、`internal` 和 `private`。可以使用以下任意一种访问级别修饰符来指定声明的访问级别。访问控制在 [访问控制](../chapter2/24_Access_Control.md) 中有详细讨论。
+
+`public`
+
+该修饰符表示声明可被同模块的代码访问,只要其他模块导入了声明所在的模块,也可以进行访问。
+
+`internal`
+
+该修饰符表示声明只能被同模块的代码访问。默认情况下,绝大多数声明会被隐式标记 `internal` 访问级别修饰符。
+
+`private`
+
+该修饰符表示声明只能被所在源文件的代码访问。
+
+以上访问级别修饰符都可以选择带上一个参数,该参数由一对圆括号和其中的 `set` 关键字组成(例如,`private(set)`)。使用这种形式的访问级别修饰符来限制某个属性或下标的 setter 的访问级别低于其本身的访问级别,正如 [Getter 和 Setter](../chapter2/24_Access_Control.md#getters_and_setters) 中所讨论的。
+
+
+> 声明修饰符的语法
+
+
+> *声明修饰符* → **class** | **convenience**| **dynamic** | **final** | **infix** | **lazy** | **mutating** | **nonmutating** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
+> 声明修饰符 → [*访问级别修饰符*](#access-level-modifier)
+>
+> *声明修饰符列表* → [*声明修饰符*](#declaration-modifier) [*声明修饰符列表*](#declaration-modifiers)可选
+
+
+>访问级别修饰符 → **internal** | **internal ( set )**
+>访问级别修饰符 → **private** | **private ( set )**
+>访问级别修饰符 → **public** | **public ( set )**
diff --git a/source/chapter3/06_Attributes.md b/source/chapter3/06_Attributes.md
index 21f5b989..bf4af714 100755
--- a/source/chapter3/06_Attributes.md
+++ b/source/chapter3/06_Attributes.md
@@ -6,218 +6,228 @@
> 校对:[numbbbbb](https://github.com/numbbbbb), [stanzhai](https://github.com/stanzhai)
> 2.0
-> 翻译+校对:[KYawn](https://github.com/KYawn),[小铁匠Linus](https://github.com/kevin833752)
+> 翻译+校对:[KYawn](https://github.com/KYawn)
+
+> 2.1
+> 翻译:[小铁匠Linus](https://github.com/kevin833752)
本页内容包括:
- [声明特性](#declaration_attributes)
+- [Interface Builder 使用的声明特性](#declaration_attributes_used_by_interface_builder)
- [类型特性](#type_attributes)
-特性提供了关于声明和类型的更多信息。在Swift中有两类特性,用于修饰声明的以及用于修饰类型的。
+特性提供了有关声明和类型的更多信息。在Swift中有两种特性,分别用于修饰声明和类型。
-通过以下方式指定一个特性:符号`@`后面跟特性名,如果包含参数,则把参数带上:
+您可以通过以下方式指定一个特性:符号`@`后跟特性的名称和特性接收的任何参数:
-> @`attribute name`
-> @`attribute name`(`attribute arguments`)
+> @ `特性名`
-有些声明特性通过接收参数来指定特性的更多信息以及它是如何修饰一个特定的声明的。这些特性的参数写在小括号内,它们的格式由它们所属的特性来定义。
+> @ `特性名`(`特性参数`)
+
+有些声明特性通过接收参数来指定特性的更多信息以及它是如何修饰某个特定的声明的。这些特性的参数写在圆括号内,它们的格式由它们所属的特性来定义。
-## 声明特性
-
-声明特性只能应用于声明。然而,你也可以将`noreturn`特性应用于函数或方法类型。
-
-`autoclosure`
-
-这个特性通过把表达式自动封装成无参数的闭包来延迟表达式的计算。它可以声明返回表达式自身类型的没有参数的方法类型,也可以用于函数参数的声明。含有`autoclosure`特性的声明同时也具有`noescape`的特性,除非传递可选参数`escaping`.关于怎样使用`autoclosure`特性的例子,参见[函数类型](./03_Types.html#function_type).
+##声明特性
+声明特性只能应用于声明。
`available`
-将`available`特性用于声明时,意味着该声明的生命周期会依赖于特定的平台和操作系统版本。
+将 `available` 特性用于声明时,表示该声明的生命周期与特定的平台和操作系统版本有关。
-`available`特性经常与参数列表一同出现,该参数列表至少有两个参数,参数之间由逗号分隔。这些参数由以下这些平台名字中的一个起头:
+`available` 特性经常与参数列表一同出现,该参数列表至少有两个特性参数,参数之间由逗号分隔。这些参数由以下这些平台名字中的一个起头:
-- `iOS`
-- `iOSApplicationExtension`
-- `OSX`
-- `OSXApplicationExtension`
-- `watchOS`
+- iOS
+- iOSApplicationExtension
+- macOS
+- macOSApplicationExtension
+- watchOS
+- watchOSApplicationExtension
+- tvOS
+- tvOSApplicationExtension
-当然,你也可以用一个星号(*)来表示,该声明在上面提到的所有平台上都是有效的。
+当然,你也可以用一个星号(*)来表示上面提到的所有平台。
+其余的参数,可以按照任何顺序出现,并且可以添加关于声明生命周期的附加信息,包括重要事件。
-剩下的参数,可以以任何顺序出现,并且可以添加关于声明生命周期的附加信息,包括重要的里程碑。
+- `unavailable`参数表示该声明在指定的平台上是无效的。
+- `introduced` 参数表示指定平台从哪一版本开始引入该声明。格式如下:
-- `unavailable`参数表示:该声明在特定的平台上是无效的
+`introduced`=`版本号`
-- `introduced`参数表示:该声明第一次被引入时所在平台的版本。格式如下:
-`introduced=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。
+*版本号*由一个或多个正整数构成,由句点分隔的。
-- `deprecated`参数表示:该声明第一次被建议弃用时所在平台的版本。格式如下:
-
`deprecated=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。
+- `deprecated`参数表示指定平台从哪一版本开始弃用该声明。格式如下:
-- `obsoleted`参数表示:该声明第一次被弃用时所在平台的版本。当一个声明被弃用时,它就从此平台中被移除,不能再被使用。格式如下:
-
`obsoleted=version number`
这里的`version number`由一个正的十进制整数或浮点数构成。
+`deprecated`=`版本号`
-- `message`参数用来提供文本信息。当使用建议弃用或者被弃用的声明时,编译器会抛出错误或警告信息。格式如下:
-
`message=message`
这里的`message`由一个字符串文字构成。
+可选的*版本号*由一个或多个正整数构成,由句点分隔的。省略版本号表示该声明目前已弃用,当弃用出现时无需给出任何有关信息。如果你省略了版本号,冒号(:)也可省略。
-- `renamed`参数用来提供文本信息,用以表示被重命名的声明的新名字。当使用这个重命名的声明遇到错误时,编译器会显示出该新名字。格式如下:
-
`renamed=new name`
这里的`new name`由一个字符串文字构成。
+- `obsoleted` 参数表示指定平台从哪一版本开始废弃该声明。当一个声明被废弃后,它就从平台中移除,不能再被使用。格式如下:
-你可以将`renamed`参数和`unavailable`参数以及类型别名声明组合使用,以向用户表示:在你的代码中,一个声明已经被重命名。当一个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当有用。
+`obsoleted`=`版本号`
+
+*版本号*由一个或多个正整数构成,由句点分隔的。
+
+- `message` 参数用来提供文本信息。当使用被弃用或者被废弃的声明时,编译器会抛出警告或错误信息。格式如下:
+
+`message`=`信息内容`
+
+信息内容由一个字符串构成。
+
+- `renamed` 参数用来提供文本信息,用以表示被重命名的声明的新名字。当使用声明的旧名字时,编译器会报错提示新名字。格式如下:
+
+`renamed`=`新名字`
+
+新名字由一个字符串构成。
+
+你可以将`renamed` 参数和 `unavailable` 参数以及类型别名声明组合使用,以此向用户表示某个声明已经被重命名。当某个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当有用。
```swift
-// First release
+// 首发版本
protocol MyProtocol {
- // protocol definition
-}
-```
-
-```swift
-// Subsequent release renames MyProtocol
-protocol MyRenamedProtocol {
- // protocol definition
+// 这里是协议定义
}
-
-@available(*, unavailable, renamed="MyRenamedProtocol")
+```
+
+```swift
+// 后续版本重命名了 MyProtocol
+protocol MyRenamedProtocol {
+// 这里是协议定义
+}
+@available(*, unavailable, renamed:"MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol
```
-你可以在一个单独的声明上使用多个`available`特性,以详细说明该声明在不同平台上的有效性。编译器只有在当前的目标平台和`available`特性中指定的平台匹配时,才会使用`available`特性。
+你可以在某个声明上使用多个 `available` 特性,以指定该声明在不同平台上的可用性。编译器只有在当前目标平台和 `available` 特性中指定的平台匹配时,才会使用 `available` 特性。
-如果`available`特性除了平台名称参数外,只指定了一个`introduced `参数,那么可以使用以下简写语法代替:
+如果 `available` 特性除了平台名称参数外,只指定了一个 `introduced` 参数,那么可以使用以下简写语法代替:
-@available(`platform name` `version number`, *)
+@available(平台名称 版本号,*)
-`available`特性的简写语法可以简明地表达出多个平台的可用性。尽管这两种形式在功能上是相同的,但请尽可能地使用简明语法形式。
+`available` 特性的简写语法可以简明地表达出声明在多个平台上的可用性。尽管这两种形式在功能上是相同的,但请尽可能地使用简写语法形式。
```swift
-@available(iOS 8.0, OSX 10.10, *)
+@available(iOS 10.0, macOS 10.12, *)
class MyClass {
- // class definition
+// 这里是类定义
}
```
+`discardableResult`
+
+该特性用于的函数或方法声明,以抑制编译器中 函数或方法的返回值被调而没有使用其结果的警告。
+
+`GKInspectable`
+
+应用此属性,暴露一个自定义GameplayKit组件属性给SpriteKit编辑器UI。
+
`objc`
-该特性用于修饰任何可以在Objective-C中表示的声明。比如,非嵌套类、协议、非泛型枚举(仅限整型值类型)、类和协议的属性和方法(包括`getter`和`setter`)、构造器、析构器以及下标。`objc`特性告诉编译器这个声明可以在Objective-C代码中使用。
+该特性用于修饰任何可以在 Objective-C 中表示的声明。比如,非嵌套类、协议、非泛型枚举(仅限原始值为整型的枚举)、类和协议中的属性和方法(包括存取方法)、构造器、析构器以及下标运算符。`objc` 特性告诉编译器这个声明可以在 Objective-C 代码中使用。
-标有`objc`特性的类必须继承自Objective-C中定义的类。如果你将`objc`特性应用于一个类或协议,它也会隐式地应用于那个类的成员或协议。对于标记了`objc`特性的类,编译器会隐式地为它的子类添加`objc`特性。标记了`objc`特性的协议不能继承没有标记`objc`的协议。
+标有 `objc` 特性的类必须继承自 Objective-C 中定义的类。如果你将 `objc` 特性应用于一个类或协议,它也会隐式地应用于类或协议中兼容 Objective-C 的成员。对于标记了 `objc` 特性的类,编译器会隐式地为它的子类添加 `objc` 特性。标记了 `objc` 特性的协议不能继承没有标记 `objc` 的协议。
-如果你将`objc`特性应用于枚举,每一个枚举的`case`都会以枚举名称和`case`名称组合的方式暴露在Objective-C代码中。例如:一个名为`Venus`的`case`在`Planet`枚举中,这个`case`暴露在Objective-C代码中时叫做`PlanetVenus`。
+如果你将 `objc` 特性应用于枚举,每一个枚举用例都会以枚举名称和用例名称组合的方式暴露在 Objective-C 代码中。例如,在 `Planet` 枚举中有一个名为 `Venus` 的用例,该用例暴露在 Objective-C 代码中时叫做 `PlanetVenus`。
-`objc`特性有一个可选的参数,由标记符组成。当你想把`objc`所修饰的实体以一个不同的名字暴露给Objective-C时,你就可以使用这个特性参数。你可以使用这个参数来命名类,协议,方法,getters,setters,以及构造器。下面的例子把`ExampleClass`中`enabled`属性的getter暴露给Objective-C,名字是`isEnabled`,而不是它原来的属性名。
+`objc` 特性有一个可选的参数,由标识符构成。当你想把 objc 所修饰的实体以一个不同的名字暴露给 Objective-C 时,你就可以使用这个特性参数。你可以使用这个参数来命名类、枚举类型、枚举用例、协议、方法、存取方法以及构造器。下面的例子把 `ExampleClass` 中的 `enabled` 属性的取值方法暴露给 Objective-C,名字是 `isEnabled`,而不是它原来的属性名。
```swift
@objc
class ExampleClass: NSObject {
- var enabled: Bool {
- @objc(isEnabled) get {
- // Return the appropriate value
- }
- }
+var enabled: Bool {
+@objc(isEnabled) get {
+// 返回适当的值 }
+}
}
```
-
-`noescape`
-
-在函数或者方法声明上使用该特性,它表示参数将不会被存储用作后续的计算,其用来确保不会超出函数调用的生命周期。对于其属性或方法来说,使用`noescape`声明属性的函数类型不需要显式的使用`self.`。
-
`nonobjc`
-该特性用于方法、属性、下标、或构造器的声明,这些声明本是可以在Objective-C代码中表示的。使用`nonobjc`特性告诉编译器这个声明不能在Objective-C代码中使用。
+该特性用于方法、属性、下标、或构造器的声明,这些声明本可以在 Objective-C 代码中使用,而使用 `nonobjc` 特性则告诉编译器这个声明不能在 Objective-C 代码中使用。
-可以使用`nonobjc`特性解决标有`objc`的类中桥接方法的循环问题,该特性还允许标有`objc`的类的构造器和方法进行重载(overload)。
+可以使用 `nonobjc` 特性解决标有 `objc` 的类中桥接方法的循环问题,该特性还允许对标有 `objc` 的类中的构造器和方法进行重载。
-标有`nonobjc`特性的方法不能重写(override)一个标有`objc`特性的方法。然而,标有`objc`特性的方法可以重写标有`nonobjc`特性的方法。同样,标有`nonobjc`特性的方法不能满足一个需要标有`@objc`特性的方法的协议。
-
-`noreturn`
-
-该特性用于修饰函数或方法声明,表明该函数或方法的对应类型,`T`,是`@noreturn T`。你可以用这个特性修饰函数或方法的类型,这样一来,函数或方法就不会返回到它的调用者中去。
-
-对于一个没有用`noreturn`特性标记的函数或方法,你可以将它重写为用该特性标记的。相反,对于一个已经用`noreturn`特性标记的函数或方法,你则不可以将它重写为没使用该特性标记的。当你在一个comforming类型中实现一个协议方法时,该规则同样适用。
+标有 `nonobjc` 特性的方法不能重写标有 `objc` 特性的方法。然而,标有 `objc` 特性的方法可以重写标有 `nonobjc` 特性的方法。同样,标有 `nonobjc` 特性的方法不能满足标有 `@objc` 特性的协议中的方法要求。
`NSApplicationMain`
-在类上使用该特性表示该类是应用程序委托类,使用该特性与调用`NSApplicationMain(_:_:)`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
+在类上使用该特性表示该类是应用程序委托类,使用该特性与调用 `NSApplicationMain`(\_:_:) 函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
-如果你不想使用这个特性,可以提供一个`main.swift`文件,并且提供一个`main()`函数去调用`NSApplicationMain(_:_:)`函数。比如,如果你的应用程序使用一个派生于`NSApplication`的自定义子类作为主要类,你可以调用`NSApplicationMain`函数而不是使用该特性。
+如果你不想使用这个特性,可以提供一个 main.swift 文件,并在代码**顶层**调用`NSApplicationMain`(\_:_:) 函数,如下所示:
+```swift
+import AppKit
+NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
+```
`NSCopying`
-该特性用于修饰一个类的存储型变量属性。该特性将使属性的setter与属性值的一个副本合成,这个值由`copyWithZone(_:)`方法返回,而不是属性本身的值。该属性的类型必需遵循`NSCopying`协议。
+该特性用于修饰一个类的存储型变量属性。该特性将使属性的设值方法使用传入值的副本进行赋值,这个值由传入值的 `copyWithZone`(\_:) 方法返回。该属性的类型必需符合 `NSCopying` 协议。
-`NSCopying`特性的原理与Objective-C中的`copy`特性相似。
+`NSCopying` 特性的行为与 Objective-C 中的 `copy` 特性相似。
`NSManaged`
-该特性用于修饰`NSManagedObject`子类中的实例方法或存储型变量属性,表明属性的存储和实现由Core Data在运行时基于相关实体描述动态提供。对于标记了`NSManaged`特性的属性,Core Data也会在运行时提供存储。
+该特性用于修饰 `NSManagedObject` 子类中的实例方法或存储型变量属性,表明它们的实现由 `Core Data` 在运行时基于相关实体描述动态提供。对于标记了 `NSManaged` 特性的属性,`Core Data` 也会在运行时为其提供存储。应用这个特性也意味着`objc`特性。
`testable`
-该特性用于`import`声明可以测试的编译模块,它能访问任何标有`internal`权限标识符的实体,这和将它声明为`public`权限标识符有同样的效果。
+在导入允许测试的编译模块时,该特性用于修饰 `import` 声明,这样就能访问被导入模块中的任何标有 `internal` 访问级别修饰符的实体,犹如它们被标记了 `public` 访问级别修饰符。测试也可以访问使用`internal`或者`public`访问级别修饰符标记的类和类成员,就像它们是`open`访问修饰符声明的。
`UIApplicationMain`
-在类上使用该特性表示该类是应用程序委托类,使用该特性与调用`UIApplicationMain(_:_:)`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
+在类上使用该特性表示该类是应用程序委托类,使用该特性与调用 `UIApplicationMain`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
-如果你不想使用这个特性,可以提供一个`main.swift`文件,并且提供一个`main`函数去调用`UIApplicationMain(_:_:)`函数。比如,如果你的应用程序使用一个派生于`UIApplication`的自定义子类作为主要类,你可以调用`UIApplicationMain`函数而不是使用该特性。
+如果你不想使用这个特性,可以提供一个 main.swift 文件,并在代码顶层调用 `UIApplicationMain`(\_:\_:\_:) 函数。比如,如果你的应用程序使用一个继承于 UIApplication 的自定义子类作为主要类,你可以调用 `UIApplicationMain`(\_:\_:\_:) 函数而不是使用该特性。
-`warn_unused_result`
+
+###Interface Builder 使用的声明特性
+`Interface Builder` 特性是 `Interface Builder` 用来与 Xcode 同步的声明特性。`Swift` 提供了以下的 `Interface Builder` 特性:`IBAction`,`IBOutlet`,`IBDesignable`,以及`IBInspectable` 。这些特性与 Objective-C 中对应的特性在概念上是相同的。
-该特性应用于方法或函数声明,当方法或函数被调用,但其结果未被使用时,该特性会让编译器会产生警告。
+`IBOutlet` 和 `IBInspectable` 用于修饰一个类的属性声明,`IBAction` 特性用于修饰一个类的方法声明,`IBDesignable` 用于修饰类的声明。
-你可以使用这个特性提供一个警告信息,这个警告信息是关于不正确地使用未变异的方法,这个方法也有一个对应的变异方法。
-
-`warn_unused_result`特性会有选择地采用下面两个参数之一。
-
-- `message`参数用来提供警告信息。在当方法或函数被调用,但其结果未被使用时,会显示警告信息。格式如下:
-
`message=message`
这里的`message`由一个字符串文字构成。
-
-- `mutable_variant`参数用于提供变异方法的名称,如果未变异方法以一个可变的值被调用而且其结果并未被使用时,应该使用此变异方法。格式如下(方法名有字符串构成):
`mutable_variant=method name`
-比如,Swift标准库同时提供了变异方法`sortInPlace()`和未变异方法`sort()`集合,它们的元素生成器符合`Comparable`协议。如果你调用了`sort()`方法,而没有使用它的结果,其实很有可能,你是打算使用变异方法`sortInPlace()`。
-
-### Interface Builder使用的声明特性
-
-Interface Builder特性是Interface Builder用来与Xcode同步的声明特性。Swift提供了以下的Interface Builder特性:`IBAction`,`IBDesignable`,`IBInspectable`,以及`IBOutlet`。这些特性与Objective-C中对应的特性在概念上是相同的。
-
-`IBOutlet`和`IBInspectable`用于修饰一个类的属性声明;`IBAction`特性用于修饰一个类的方法声明;`IBDesignable`用于修饰类的声明。
+`IBAction` 和 `IBOutlet` 特性都意味着`objc`特性。
-## 类型特性
+##类型特性
+类型特性只能用于修饰类型。
-类型特性只能用于修饰类型。然而,你也可以用`noreturn`特性去修饰函数或方法声明。
+`autoclosure`
+
+这个特性通过把表达式自动封装成无参数的闭包来延迟表达式的计算。它可以修饰类型为返回表达式结果类型的无参数函数类型的函数参数。关于如何使用 autoclosure 特性的例子,请参阅 [自动闭包](http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html/) 和 [函数类型](http://wiki.jikexueyuan.com/project/swift/chapter3/03_Types.html)。
`convention`
+该特性用于修饰函数类型,它指出了函数调用的约定。
-该特性用于函数的类型,它指出函数调用的约定。
+convention 特性总是与下面的参数之一一起出现。
-`convention`特性总是与下面的参数之一一起出现。
+- `swift` 参数用于表示一个 Swift 函数引用。这是 Swift 中函数值的标准调用约定。
-- `swift`参数用于表明一个Swift函数引用。这是Swift中标准的函数值调用约定。
+- `block` 参数用于表示一个 Objective-C 兼容的块引用。函数值会作为一个块对象的引用,块是一种 `id` 兼容的 Objective-C 对象,其中嵌入了调用函数。调用函数使用 C 的调用约定。
-- `block`参数用于表明一个Objective-C兼容的块引用。函数值表示为一个块对象的引用,这是一个`id-`兼容的Objective-C对象,对象中嵌入了调用函数。调用函数使用C的调用约定。
+- `c` 参数用于表示一个 C 函数引用。函数值没有上下文,不具备捕获功能,同样使用 C 的调用约定。
-- `c`参数用于表明一个C函数引用。函数值没有上下文,这个函数也使用C的调用约定。
+使用 C 函数调用约定的函数也可用作使用 Objective-C 块调用约定的函数,同时使用 Objective-C 块调用约定的函数也可用作使用 Swift 函数调用约定的函数。然而,只有非泛型的全局函数、局部函数以及未捕获任何局部变量的闭包,才可以被用作使用 C 函数调用约定的函数。
-使用C函数调用约定的函数也可用作使用Objective-C块调用约定的函数,同时使用Objective-C块调用约定的函数也可用作使用Swift函数调用约定的函数。然而,只有非泛型的全局函数和本地函数或者不使用任何本地变量的闭包可以被用作使用C函数调用约定的函数。
+`escaping`
+在函数或者方法声明上使用该特性,它表示参数将不会被存储以供延迟执行,这将确保参数不会超出函数调用的生命周期。在使用 `escaping` 声明特性的函数类型中访问属性和方法时不需要显式地使用 `self.`。关于如何使用 `escaping` 特性的例子,请参阅 [逃逸闭包](http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html)。
-`noreturn`
+>特性语法
-该特性用于修饰函数或方法的类型,表明该函数或方法不会返回到它的调用者中去。你也可以用它标记函数或方法的声明,表示函数或方法的相应类型,`T`,是`@noreturn T`。
+> *特性 *→ @ 特性名 特性参数子句可选
-> 特性语法
-> *特性* → **@** [*特性名*](#attribute_name) [*特性参数子句*](#attribute_argument_clause) (可选)
-> *特性名* → [*标识符*](02_Lexical_Structure.html#identifiers)
-> *特性参数子句* → **(** [*平衡令牌列表*](#balanced_tokens) (可选) **)**
-> *特性(Attributes)列表* → [*特色*](#attribute) [*特性(Attributes)列表*](#attributes) (可选)
-> *平衡令牌列表* → [*平衡令牌*](#balanced_token) [*平衡令牌列表*](#balanced_tokens) (可选)
-> *平衡令牌* → **(** [*平衡令牌列表*](#balanced_tokens) (可选) **)**
-> *平衡令牌* → **[** [*平衡令牌列表*](#balanced_tokens) (可选) **]**
-> *平衡令牌* → **{** [*平衡令牌列表*](#balanced_tokens) (可选) **}**
-> *平衡令牌* → **任意标识符, 关键字, 字面量或运算符**
-> *平衡令牌* → **任意标点除了(, ), [, ], {, 或 }**
+> *特性名* → 标识符
+> *特性参数子句* → ( 均衡令牌列表可选 )
+> *特性列表* → 特性 特性列表可选
+> *均衡令牌列表* → 均衡令牌 均衡令牌列表可选
+> *均衡令牌* → ( 均衡令牌列表可选 )
+
+> *均衡令牌* → [ 均衡令牌列表可选 ]
+
+> *均衡令牌* → { 均衡令牌列表可选}
+
+> *均衡令牌* → 任意标识符,关键字,字面量或运算符
+
+> *均衡令牌* → 任意标点除了 (,),[,],{,或 }
diff --git a/source/chapter3/07_Patterns.md b/source/chapter3/07_Patterns.md
index d9aa54c2..058c338e 100755
--- a/source/chapter3/07_Patterns.md
+++ b/source/chapter3/07_Patterns.md
@@ -1,13 +1,15 @@
# 模式(Patterns)
------------------
-
+-----------------
+
> 1.0
> 翻译:[honghaoz](https://github.com/honghaoz)
> 校对:[numbbbbb](https://github.com/numbbbbb), [stanzhai](https://github.com/stanzhai)
> 2.0
-> 翻译+校对:[ray16897188](https://github.com/ray16897188),
-> [BridgeQ](https://github.com/WXGBridgeQ)
+> 翻译+校对:[ray16897188](https://github.com/ray16897188),
+
+> 2.1
+> 翻译:[BridgeQ](https://github.com/WXGBridgeQ)
本页内容包括:
@@ -17,97 +19,101 @@
- [元组模式(Tuple Pattern)](#tuple_pattern)
- [枚举用例模式(Enumeration Case Pattern)](#enumeration_case_pattern)
- [可选模式(Optional Pattern)](#optional_pattern)
-- [类型转换模式(Type-Casting Pattern)](#type-casting_pattern)
+- [类型转换模式(Type-Casting Pattern)](#type-casting_patterns)
- [表达式模式(Expression Pattern)](#expression_pattern)
-模式(pattern)代表了单个值或者复合值的结构。例如,元组`(1, 2)`的结构是逗号分隔的,包含两个元素的列表。因为模式代表一种值的结构,而不是特定的某个值,你可以把模式和各种同类型的值匹配起来。比如,`(x, y)`可以匹配元组`(1, 2)`,以及任何含两个元素的元组。除了将模式与一个值匹配外,你可以从复合值中提取出部分或全部,然后分别把各个部分和一个常量或变量绑定起来。
+模式代表单个值或者复合值的结构。例如,元组 `(1, 2)` 的结构是由逗号分隔的,包含两个元素的列表。因为模式代表一种值的结构,而不是特定的某个值,你可以利用模式来匹配各种各样的值。比如,`(x, y)` 可以匹配元组 `(1, 2)`,以及任何含两个元素的元组。除了利用模式匹配一个值以外,你可以从复合值中提取出部分或全部值,然后分别把各个部分的值和一个常量或变量绑定起来。
-swift语言中模式有2个基本的分类:一类能成功和任何值的类型相匹配,另一类在运行时(runtime)和某特定值匹配时可能会失败。
+Swift 中的模式分为两类:一种能成功匹配任何类型的值,另一种在运行时匹配某个特定值时可能会失败。
-第一类模式用于解构简单变量,常量和可选绑定中的值。此类模式包括通配符模式(wildcard patterns),标识符模式(identifier patterns),以及任何包含了它们的值绑定模式(value binding patterns)或者元祖模式(tuple patterns)。你可以为这类模式指定一个类型标注(type annotation)从而限制它们只能匹配某种特定类型的值。
+第一类模式用于解构简单变量、常量和可选绑定中的值。此类模式包括通配符模式、标识符模式,以及包含前两种模式的值绑定模式和元组模式。你可以为这类模式指定一个类型标注,从而限制它们只能匹配某种特定类型的值。
-第二类模式用于全模式匹配,这种情况下你用来相比较的值在运行时可能还不存在。此类模式包括枚举用例模式(enumeration case patterns),可选模式(optional patterns),表达式模式(expression patterns)和类型转换模式(type-casting patterns)。你在`switch`语句的case标签中,`do`语句的`catch`从句中,或者在`if, while, guard`和`for-in`语句的case条件句中使用这类模式。
+第二类模式用于全模式匹配,这种情况下你试图匹配的值在运行时可能不存在。此类模式包括枚举用例模式、可选模式、表达式模式和类型转换模式。你在 `switch` 语句的 `case` 标签中,`do` 语句的 `catch` 子句中,或者在 `if`、`while`、`guard` 和 `for-in` 语句的 `case` 条件句中使用这类模式。
-> 模式(Patterns) 语法
-> *模式* → [*通配符模式*](../chapter3/07_Patterns.html#wildcard_pattern) [*类型标注*](../chapter3/03_Types.html#type_annotation) _可选_
-> *模式* → [*标识符模式*](../chapter3/07_Patterns.html#identifier_pattern) [*类型标注*](../chapter3/03_Types.html#type_annotati(Value Binding)on) _可选_
-> *模式* → [*值绑定模式*](../chapter3/07_Patterns.html#value_binding_pattern)
-> *模式* → [*元组模式*](../chapter3/07_Patterns.html#tuple_pattern) [*类型标注*](../chapter3/03_Types.html#type_annotation) _可选_
-> *模式* → [*枚举用例模式*](../chapter3/07_Patterns.html#enum_case_pattern)
-> *模式* → [*可选模式*](../chapter3/07_Patterns.html#optional_pattern)
-> *模式* → [*类型转换模式*](../chapter3/07_Patterns.html#type_casting_pattern)
-> *模式* → [*表达式模式*](../chapter3/07_Patterns.html#expression_pattern)
+> 模式语法
+
+> *模式* → [*通配符模式*](#wildcard_pattern) [*类型标注*](03_Types.md#type-annotation)可选
+> *模式* → [*标识符模式*](#identifier_pattern) [*类型标注*](03_Types.md#type-annotation)可选
+> *模式* → [*值绑定模式*](#value-binding-pattern)
+> *模式* → [*元组模式*](#tuple-pattern) [*类型标注*](03_Types.md#type-annotation)可选
+> *模式* → [*枚举用例模式*](#enum-case-pattern)
+> *模式* → [*可选模式*](#optional-pattern)
+> *模式* → [*类型转换模式*](#type-casting-pattern)
+> *模式* → [*表达式模式*](#expression-pattern)
## 通配符模式(Wildcard Pattern)
-通配符模式由一个下划线(_)构成,且匹配并忽略任何值。当你不在乎被匹配的值时可以使用该模式。例如,下面这段代码在闭区间`1...3`中循环,每次循环时忽略该区间内的当前值:
+通配符模式由一个下划线(`_`)构成,用于匹配并忽略任何值。当你想忽略被匹配的值时可以使用该模式。例如,下面这段代码在闭区间 `1...3` 中迭代,每次迭代都忽略该区间的当前值:
```swift
for _ in 1...3 {
- // Do something three times.
+ // ...
}
```
> 通配符模式语法
+
> *通配符模式* → **_**
## 标识符模式(Identifier Pattern)
-标识符模式匹配任何值,并将匹配的值和一个变量或常量绑定起来。例如,在下面的常量声明中,`someValue`是一个标识符模式,匹配了类型是`Int`的`42`。
+标识符模式匹配任何值,并将匹配的值和一个变量或常量绑定起来。例如,在下面的常量声明中,`someValue` 是一个标识符模式,匹配了 `Int` 类型的 `42`:
```swift
let someValue = 42
```
-当匹配成功时,`42`被绑定(赋值)给常量`someValue`。
+当匹配成功时,`42` 被绑定(赋值)给常量 `someValue`。
-如果一个变量或常量声明的左边的模式是一个标识符模式,那么这个标识符模式是一个隐式的值绑定模式(value-binding pattern)。
+如果一个变量或常量声明的左边是一个标识符模式,那么这个标识符模式是值绑定模式的子模式。
> 标识符模式语法
-> *标识符模式* → [*标识符*](LexicalStructure.html#identifier)
+
+> *标识符模式* → [*标识符*](02_Lexical_Structure.md#identifier)
## 值绑定模式(Value-Binding Pattern)
-值绑定模式把匹配到的值绑定给一个变量或常量名。把绑定匹配到的值绑定给常量时,用关键字`let`,绑定给变量时,用关键字`var`。
+值绑定模式把匹配到的值绑定给一个变量或常量。把匹配到的值绑定给常量时,用关键字 `let`,绑定给变量时,用关键字 `var`。
-在值绑定模式中的标识符模式会把新命名的变量或常量与匹配值做绑定。例如,你可以拆开一个元组的元素,然后把每个元素绑定到其相应一个的标识符模式中。
+在值绑定模式中的标识符模式会把新命名的变量或常量与匹配到的值做绑定。例如,你可以拆开一个元组,然后把每个元素绑定到相应的标识符模式中。
```swift
let point = (3, 2)
switch point {
- // Bind x and y to the elements of point.
+// 将 point 中的元素绑定到 x 和 y
case let (x, y):
print("The point is at (\(x), \(y)).")
}
-// prints "The point is at (3, 2).”
+// 打印 “The point is at (3, 2).”
```
-在上面这个例子中,`let`将元组模式`(x, y)`分配到各个标识符模式。正是由于这么做,`switch`语句中`case let (x, y):`和`case (let x, let y):`匹配到的值是一样的。
+在上面这个例子中,`let` 会分配到元组模式 `(x, y)` 中的各个标识符模式。因此,`switch` 语句中 `case let (x, y):` 和 `case (let x, let y):` 的匹配效果是一样的。
-> 值绑定(Value Binding)模式语法
-> *值绑定模式* → **var** [*模式*](../chapter3/07_Patterns.html#pattern) | **let** [*模式*](../chapter3/07_Patterns.html#pattern)
+> 值绑定模式语法
+
+> *值绑定模式* → **var** [*模式*](#pattern) | **let** [*模式*](#pattern)
-## 元组模式(Tuple Pattern)
+## 元组模式
-元组模式是逗号分隔的,有零个或多个模式的列表,并被一对圆括号括起来。元组模式匹配相应元组类型的值。
+元组模式是由逗号分隔的,具有零个或多个模式的列表,并由一对圆括号括起来。元组模式匹配相应元组类型的值。
-你可以使用类型标注去限制一个元组模式能匹配哪些种元组类型。例如,在常量声明`let (x, y): (Int, Int) = (1, 2)`中的元组模式`(x, y): (Int, Int)`只匹配两个元素都是`Int`这种类型的元组。如果仅需要限制一个元组模式中的某几个元素,只需要直接对这几个元素提供类型标注即可。例如,在`let (x: String, y)`中的元组模式可以和任何有两个元素,且第一个元素类型是`String`的元组类型匹配。
+你可以使用类型标注去限制一个元组模式能匹配哪种元组类型。例如,在常量声明 `let (x, y): (Int, Int) = (1, 2)` 中的元组模式 `(x, y): (Int, Int)` 只匹配两个元素都是 `Int` 类型的元组。
-当元组模式被用在`for-in`语句或者变量或常量声明时,它仅可以包含通配符模式,标识符模式,可选模式或者其他包含这些模式的元祖模式。比如下面这段代码就不正确,因为`(x, 0)`中的元素`0`是一个表达式模式:
+当元组模式被用于 `for-in` 语句或者变量和常量声明时,它仅可以包含通配符模式、标识符模式、可选模式或者其他包含这些模式的元组模式。比如下面这段代码就不正确,因为 `(x, 0)` 中的元素 `0` 是一个表达式模式:
```swift
let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
-// This code isn't valid.
+// 下面的代码是错误的
for (x, 0) in points {
/* ... */
}
```
-对于只包含一个元素的元组,括号是不起作用的。模式只匹配这个单个元素的类型。举例来说,下面3条语句是等效的:
+只包含一个元素的元组模式的圆括号没有效果,模式只匹配这个单个元素的类型。举例来说,下面的语句是等效的:
```swift
let a = 2 // a: Int = 2
@@ -116,80 +122,89 @@ let (a): Int = 2 // a: Int = 2
```
> 元组模式语法
-> *元组模式* → **(** [*元组模式元素列表*](../chapter3/07_Patterns.html#tuple_pattern_element_list) _可选_ **)**
-> *元组模式元素列表* → [*元组模式元素*](../chapter3/07_Patterns.html#tuple_pattern_element) | [*元组模式元素*](../chapter3/07_Patterns.html#tuple_pattern_element) **,** [*元组模式元素列表*](../chapter3/07_Patterns.html#tuple_pattern_element_list)
-> *元组模式元素* → [*模式*](../chapter3/07_Patterns.html#pattern)
+
+> *元组模式* → **(** [*元组模式元素列表*](#tuple-pattern-element-list)可选 **)**
+
+> *元组模式元素列表* → [*元组模式元素*](#tuple-pattern-element) | [*元组模式元素*](#tuple-pattern-element) **,** [*元组模式元素列表*](#tuple-pattern-element-list)
+
+> *元组模式元素* → [*模式*](#pattern)
## 枚举用例模式(Enumeration Case Pattern)
-一个枚举用例模式匹配现有的某个枚举类型的某个用例(case)。枚举用例模式出现在`switch`语句中的case标签中,以及`if`,`while`,`guard`和`for-in`语句的case条件中。
+枚举用例模式匹配现有的某个枚举类型的某个用例。枚举用例模式出现在 `switch` 语句中的 `case` 标签中,以及 `if`、`while`、`guard` 和 `for-in` 语句的 `case` 条件中。
-如果你准备匹配的枚举用例有任何关联的值,则相应的枚举用例模式必须指定一个包含每个关联值元素的元组模式。关于使用`switch`语句来匹配包含关联值枚举用例的例子,请参阅`Associated Values`.
+如果你准备匹配的枚举用例有任何关联的值,则相应的枚举用例模式必须指定一个包含每个关联值元素的元组模式。关于使用 `switch` 语句来匹配包含关联值的枚举用例的例子,请参阅 [关联值](../chapter2/08_Enumerations.md#associated_values)。
> 枚举用例模式语法
-> *enum-case-pattern* → [*类型标识*](../chapter3/03_Types.html#type_identifier) _可选_ **.** [*枚举的case名*](../chapter3/05_Declarations.html#enum_case_name) [*元组模式*](../chapter3/07_Patterns.html#tuple_pattern) _可选_
+
+> *枚举用例模式* → [*类型标识*](03_Types.md#type-identifier)可选 **.** [*枚举用例名*](05_Declarations.md#enum-case-name) [*元组模式*](#tuple-pattern)可选
## 可选模式(Optional Pattern)
-可选模式与封装在一个`Optional(Wrapped)`或者一个`ExplicitlyUnwrappedOptional(Wrapped)`枚举中的`Some(Wrapped)`用例相匹配。可选模式由一个标识符模式和紧随其后的一个问号组成,在某些情况下表现为枚举用例模式。
+可选模式匹配包装在一个 `Optional(Wrapped)` 或者 `ExplicitlyUnwrappedOptional(Wrapped)` 枚举中的 `Some(Wrapped)` 用例中的值。可选模式由一个标识符模式和紧随其后的一个问号组成,可以像枚举用例模式一样使用。
-由于可选模式是`optional`和`ImplicitlyUnwrappedOptional`枚举用例模式的语法糖(syntactic sugar),下面的2种写法是一样的:
+由于可选模式是 `Optional` 和 `ImplicitlyUnwrappedOptional` 枚举用例模式的语法糖,下面两种写法是等效的:
```swift
let someOptional: Int? = 42
-// Match using an enumeration case pattern
+// 使用枚举用例模式匹配
if case .Some(let x) = someOptional {
print(x)
}
-// Match using an optional pattern
+// 使用可选模式匹配
if case let x? = someOptional {
print(x)
}
```
-如果一个数组的元素是可选类型,可选模式为`for-in`语句提供了一种在该数组中迭代的简便方式,只为数组中的非空`non-nil`元素执行循环体。
+
+可选模式为 `for-in` 语句提供了一种迭代数组的简便方式,只为数组中非 `nil` 的元素执行循环体。
```swift
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
-// Match only non-nil values
+// 只匹配非 nil 的元素
for case let number? in arrayOfOptinalInts {
print("Found a \(number)")
}
-//Found a 2
-//Found a 3
-//Found a 5
-
+// Found a 2
+// Found a 3
+// Found a 5
```
+
> 可选模式语法
-> *可选模式* → [*标识符模式*](../chapter3/03_Types.html#type_identifier) ?
+
+> *可选模式* → [*标识符模式*](03_Types.md#type-identifier) **?**
## 类型转换模式(Type-Casting Patterns)
-有两种类型转换模式,`is`模式和`as`模式。这两种模式只出现在`switch`语句中的case标签中。`is`模式和`as`模式有以下形式:
+有两种类型转换模式,`is` 模式和 `as` 模式。`is` 模式只出现在 `switch` 语句中的 `case` 标签中。`is` 模式和 `as` 模式形式如下:
-> is `type`
-> `pattern` as `type`
+> is `类型`
+> `模式` as `类型`
-`is`模式仅当一个值的类型在运行时(runtime)和`is`模式右边的指定类型一致 - 或者是该类型的子类 - 的情况下,才会匹配这个值。`is`模式和`is`操作符有相似表现,它们都进行类型转换,却舍弃返回的类型。
+`is` 模式仅当一个值的类型在运行时和 `is` 模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。`is` 模式和 `is` 运算符有相似表现,它们都进行类型转换,但是 `is` 模式没有返回类型。
-`as`模式仅当一个值的类型在运行时(runtime)和`as`模式右边的指定类型一致 - 或者是该类型的子类 - 的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成`as`模式左边指定的模式。
+`as` 模式仅当一个值的类型在运行时和 `as` 模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成 `as` 模式右边指定的类型。
-关于使用`switch`语句来匹配`is`模式和`as`模式值的例子,请参阅`Type Casting for Any and AnyObject`。
+关于使用 `switch` 语句配合 `is` 模式和 `as` 模式来匹配值的例子,请参阅 [Any 和 AnyObject 的类型转换](../chapter2/19_Type_Casting.md#type_casting_for_any_and_anyobject)。
> 类型转换模式语法
-> *type-casting-pattern* → [*is模式*](../chapter3/07_Patterns.html#is_pattern) | [*as模式*](../chapter3/07_Patterns.html#as_pattern)
-> *is模式* → **is** [*类型*](../chapter3/03_Types.html#type)
-> *as模式* → [*模式*](../chapter3/07_Patterns.html#pattern) **as** [*类型*](../chapter3/03_Types.html#type)
+
+> *类型转换模式* → [*is模式*](#is-pattern) | [*as模式*](#as-pattern)
+
+> *is模式* → **is** [*类型*](03_Types.md#type)
+
+> *as模式* → [*模式*](#pattern) **as** [*类型*](03_Types.md#type)
## 表达式模式(Expression Pattern)
-一个表达式模式代表了一个表达式的值。表达式模式只出现在`switch`语句中的`case`标签中。
+表达式模式代表表达式的值。表达式模式只出现在 `switch` 语句中的 `case` 标签中。
-由表达式模式所代表的表达式与使用了Swift标准库中`~=`操作符的输入表达式的值进行比较。如果`~=`操作符返回`true`,则匹配成功。默认情况下,`~=`操作符使用`==`操作符来比较两个相同类型的值。它也可以将一个整型数值与一个`Range`对象中的一段整数区间做匹配,正如下面这个例子所示:
+表达式模式代表的表达式会使用 Swift 标准库中的 `~=` 运算符与输入表达式的值进行比较。如果 `~=` 运算符返回 `true`,则匹配成功。默认情况下,`~=` 运算符使用 `==` 运算符来比较两个相同类型的值。它也可以将一个整型数值与一个 `Range` 实例中的一段整数区间做匹配,正如下面这个例子所示:
```swift
let point = (1, 2)
@@ -201,24 +216,26 @@ case (-2...2, -2...2):
default:
print("The point is at (\(point.0), \(point.1)).")
}
-// prints "(1, 2) is near the origin.”
+// 打印 “(1, 2) is near the origin.”
```
-你可以重载`~=`操作符来提供自定义的表达式匹配行为。比如你可以重写上面的例子,拿`point`表达式去比较字符串形式的点。
+你可以重载 `~=` 运算符来提供自定义的表达式匹配行为。比如你可以重写上面的例子,将 `point` 表达式与字符串形式表示的点进行比较。
```swift
-// Overload the ~= operator to match a string with an integer
+// 重载 ~= 运算符对字符串和整数进行比较
func ~=(pattern: String, value: Int) -> Bool {
return pattern == "\(value)"
}
+
switch point {
case ("0", "0"):
print("(0, 0) is at the origin.")
default:
print("The point is at (\(point.0), \(point.1)).")
}
-// prints "(1, 2) is near the origin.”
+// 打印 “The point is at (1, 2).”
```
> 表达式模式语法
-> *表达式模式* → [*表达式*](../chapter3/04_Expressions.html#expression)
+
+> *表达式模式* → [*表达式*](04_Expressions.md#expression)
diff --git a/source/chapter3/08_Generic_Parameters_and_Arguments.md b/source/chapter3/08_Generic_Parameters_and_Arguments.md
index fc4657f8..84e92707 100755
--- a/source/chapter3/08_Generic_Parameters_and_Arguments.md
+++ b/source/chapter3/08_Generic_Parameters_and_Arguments.md
@@ -8,34 +8,37 @@
> 2.0
> 翻译+校对:[wardenNScaiyi](https:github.com/wardenNScaiyi)
+> 3.0
+> 翻译+校对:[chenmingjia](https:github.com/chenmingjia)
+
本页包含内容:
- [泛型形参子句](#generic_parameter)
+ - [Where 子句](#where_clauses)
- [泛型实参子句](#generic_argument)
-本节涉及泛型类型、泛型函数以及泛型初始化器(**initializer**)的参数,包括形参和实参。声明泛型类型、函数或初始化器时,须指定相应的类型参数。类型参数相当于一个占位符,当实例化泛型类型、调用泛型函数或泛型初始化器时,就用具体的类型实参替代之。
+本节涉及泛型类型、泛型函数以及泛型构造器的参数,包括形参和实参。声明泛型类型、函数或构造器时,须指定相应的类型参数。类型参数相当于一个占位符,当实例化泛型类型、调用泛型函数或泛型构造器时,就用具体的类型实参替代之。
-关于 Swift 语言的泛型概述,见[泛型](../chapter2/23_Generics.md)(第二部分第23章)。
+关于 Swift 语言的泛型概述,请参阅 [泛型](../chapter2/23_Generics.md)。
## 泛型形参子句
-泛型形参子句指定泛型类型或函数的类型形参,以及这些参数的关联约束和关联类型要求(**requirement**)。泛型形参子句用尖括号(<>)包住,并且有以下两种形式:
+泛型形参子句指定泛型类型或函数的类型形参,以及这些参数相关的约束和要求。泛型形参子句用尖括号(`<>`)包住,形式如下:
> <`泛型形参列表`>
-> <`泛型形参列表` where `关联类型要求`>
泛型形参列表中泛型形参用逗号分开,其中每一个采用以下形式:
> `类型形参` : `约束`
-泛型形参由两部分组成:类型形参及其后的可选约束。类型形参只是占位符类型(如 T,U,V,Key,Value 等)的名字而已。你可以在泛型类型、函数的其余部分或者初始化器声明,包括函数或初始化器的签名中使用它(与其任何相关类型)。
+泛型形参由两部分组成:类型形参及其后的可选约束。类型形参只是占位符类型(如 `T`,`U`,`V`,`Key`,`Value` 等)的名字而已。你可以在泛型类型、函数的其余部分或者构造器声明,包括函数或构造器的签名中使用它(以及它的关联类型)。
-约束用于指明该类型形参继承自某个类或者遵守某个协议或协议的一部分。例如,在下面的泛型函数中,泛型形参`T: Comparable`表示任何用于替代类型形参`T`的类型实参必须满足`Comparable`协议。
+约束用于指明该类型形参继承自某个类或者符合某个协议或协议组合。例如,在下面的泛型函数中,泛型形参 `T: Comparable` 表示任何用于替代类型形参 `T` 的类型实参必须满足 `Comparable` 协议。
```swift
-func simpleMax(x: T, _ y: T) -> T {
+func simpleMax(_ x: T, _ y: T) -> T {
if x < y {
return y
}
@@ -43,74 +46,84 @@ func simpleMax(x: T, _ y: T) -> T {
}
```
+例如,因为 `Int` 和 `Double` 均满足`Comparable`协议,所以该函数可以接受这两种类型。与泛型类型相反,调用泛型函数或构造器时不需要指定泛型实参子句。类型实参由传递给函数或构造器的实参推断而出。
-
-如,`Int`和`Double`均满足`Comparable`协议,该函数接受任何一种类型。与泛型类型相反,调用泛型函数或初始化器时不需要指定泛型实参子句。类型实参由传递给函数或初始化器的实参推断而出。
-
-
-```
-simpleMax(17, 42) // T被推断出为Int类型
-simpleMax(3.14159, 2.71828) // T被推断出为Double类型
+```swift
+simpleMax(17, 42) // T 被推断为 Int 类型
+simpleMax(3.14159, 2.71828) // T 被推断为 Double 类型
```
-## Where 子句
+
+### Where 子句
-要想对类型形参及其关联类型指定额外关联类型要求,可以在泛型形参列表之后添加`where`子句。`where`子句由关键字`where`及其后的用逗号分割的多个关联类型要求组成。
+要想对类型形参及其关联类型指定额外要求,可以在函数体或者类型的大括号之前添加 `where` 子句。`where` 子句由关键字 `where` 及其后的用逗号分隔的一个或多个要求组成。
-`where`子句中的关联关系用于指明该类型形参继承自某个类或遵守某个协议或协议的一部分。尽管`where`子句提供了语法糖使其有助于表达类型形参上的简单约束(如`T: Comparable`等同于`T where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束。如,``表示泛型类型`T`继承自类`C`且遵守协议`P`。
+> `where` : `类型要求`
-如上所述,可以强制约束类型形参的关联类型遵守某个协议。例如``表示`T`遵守`Generator`协议,而且`T`的关联类型`T.Element`遵守`Eauatable`协议(`T`有关联类型`Element`是因为`Generator`声明了`Element`,而`T`遵守`Generator`协议)。
+`where` 子句中的要求用于指明该类型形参继承自某个类或符合某个协议或协议组合。尽管 `where` 子句提供了语法糖使其有助于表达类型形参上的简单约束(如 `` 等同于 ` where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束,例如你可以强制形参的关联类型遵守协议,如,` where S.Iterator.Element: Equatable` 表示泛型类型 `S` 遵守`Sequence`协议并且关联类型`S.Iterator.Element`遵守`Equatable`协议,这个约束确保队列的每一个元素都是符合 `Equatable` 协议的。
-也可以用操作符`==`来指定两个类型等效的关联关系。例如,有这样一个约束:`T`和`U`遵守`Generator`协议,同时要求它们的关联类型等同,可以这样来表达:``。
+也可以用操作符 `==` 来指定两个类型必须相同。例如,泛型形参子句 ` where S1.Iterator.Element == S2.Iterator.Element` 表示 `S1` 和 `S2` 必须都符合 `SequenceType` 协议,而且两个序列中的元素类型必须相同。
-当然,替代类型形参的类型实参必须满足所有类型形参的约束和关联类型要求。
+当然,替代类型形参的类型实参必须满足所有的约束和要求。
-泛型函数或初始化器可以重载,但在泛型形参子句中的类型形参必须有不同的约束或关联类型要求,抑或二者皆不同。当调用重载的泛型函数或始化器时,编译器会用这些约束来决定调用哪个重载函数或始化器。
+泛型函数或构造器可以重载,但在泛型形参子句中的类型形参必须有不同的约束或要求,抑或二者皆不同。当调用重载的泛型函数或构造器时,编译器会根据这些约束来决定调用哪个重载函数或构造器。
+更多关于泛型where从句的信息和关于泛型函数声明的例子,可以看一看 [泛型where子句](https://github.com/numbbbbb/the-swift-programming-language-in-chinese/blob/gh-pages/source/chapter2/23_Generics.md#where_clauses)
> 泛型形参子句语法
-> *泛型参数子句* → **<** [*泛型参数列表*](GenericParametersAndArguments.html#generic_parameter_list) [*约束子句*](GenericParametersAndArguments.html#requirement_clause) _可选_ **>**
-> *泛型参数列表* → [*泛形参数*](GenericParametersAndArguments.html#generic_parameter) | [*泛形参数*](GenericParametersAndArguments.html#generic_parameter) **,** [*泛型参数列表*](GenericParametersAndArguments.html#generic_parameter_list)
-> *泛形参数* → [*类型名称*](../chapter3/03_Types.html#type_name)
-> *泛形参数* → [*类型名称*](../chapter3/03_Types.html#type_name) **:** [*类型标识*](../chapter3/03_Types.html#type_identifier)
-> *泛形参数* → [*类型名称*](../chapter3/03_Types.html#type_name) **:** [*协议合成类型*](../chapter3/03_Types.html#protocol_composition_type)
-> *约束子句* → **where** [*约束列表*](GenericParametersAndArguments.html#requirement_list)
-> *约束列表* → [*约束*](GenericParametersAndArguments.html#requirement) | [*约束*](GenericParametersAndArguments.html#requirement) **,** [*约束列表*](GenericParametersAndArguments.html#requirement_list)
-> *约束* → [*一致性约束*](GenericParametersAndArguments.html#conformance_requirement) | [*同类型约束*](GenericParametersAndArguments.html#same_type_requirement)
-> *一致性约束* → [*类型标识*](../chapter3/03_Types.html#type_identifier) **:** [*类型标识*](../chapter3/03_Types.html#type_identifier)
-> *一致性约束* → [*类型标识*](../chapter3/03_Types.html#type_identifier) **:** [*协议合成类型*](../chapter3/03_Types.html#protocol_composition_type)
-> *同类型约束* → [*类型标识*](../chapter3/03_Types.html#type_identifier) **==** [*类型标识*](../chapter3/03_Types.html#type_identifier)
+
+
+> *泛型形参子句* → **<** [*泛型形参列表*](#generic-parameter-list) [*约束子句*](#requirement-clause)可选 **>**
+
+> *泛型形参列表* → [*泛形形参*](#generic-parameter) | [*泛形形参*](#generic-parameter) **,** [*泛型形参列表*](#generic-parameter-list)
+
+> *泛形形参* → [*类型名称*](03_Types.html#type-name)
+> *泛形形参* → [*类型名称*](03_Types.html#type-name) **:** [*类型标识符*](03_Types.html#type-identifier)
+> *泛形形参* → [*类型名称*](03_Types.html#type-name) **:** [*协议合成类型*](03_Types.html#protocol-composition-type)
+
+
+> *约束子句* → **where** [*约束列表*](#requirement-list)
+
+> *约束列表* → [*约束*](#requirement) | [*约束*](#requirement) **,** [*约束列表*](#requirement-list)
+
+> *约束* → [*一致性约束*](#conformance-requirement) | [*同类型约束*](#same-type-requirement)
+
+
+> *一致性约束* → [*类型标识符*](03_Types.html#type-identifier) **:** [*类型标识符*](03_Types.html#type-identifier)
+> *一致性约束* → [*类型标识符*](03_Types.html#type-identifier) **:** [*协议合成类型*](03_Types.html#protocol-composition-type)
+
+> *同类型约束* → [*类型标识符*](03_Types.html#type-identifier) **==** [*类型*](03_Types.html#type)
## 泛型实参子句
-泛型实参子句指定_泛型类型_的类型实参。泛型实参子句用尖括号(<>)包住,形式如下:
+泛型实参子句指定泛型类型的类型实参。泛型实参子句用尖括号(`<>`)包住,形式如下:
> <`泛型实参列表`>
-泛型实参列表中类型实参有逗号分开。类型实参是实际具体类型的名字,用来替代泛型类型的泛型形参子句中的相应的类型形参。从而得到泛型类型的一个特化版本。如,Swift标准库的泛型字典类型定义如下:
-
+泛型实参列表中类型实参用逗号分开。类型实参是实际具体类型的名字,用来替代泛型类型的泛型形参子句中的相应的类型形参。从而得到泛型类型的一个特化版本。例如,Swift 标准库中的泛型字典类型的的简化定义如下:
```swift
-struct Dictionary: Collection, DictionaryLiteralConvertible {
-
- /* .. */
-
+struct Dictionary: CollectionType, DictionaryLiteralConvertible {
+ /* ... */
}
```
-泛型`Dictionary`类型的特化版本,`Dictionary`就是用具体的`String`和`Int`类型替代泛型类型`KeyType: Hashable`和`ValueType`产生的。每一个类型实参必须满足它所替代的泛型形参的所有约束,包括任何`where`子句所指定的额外的关联类型要求。上面的例子中,类型形参`Key`类型要求满足`Hashable`协议,因此`String`也必须满足`Hashable`协议。
+泛型 `Dictionary` 类型的特化版本,`Dictionary` 就是用具体的 `String` 和 `Int` 类型替代泛型类型 `Key: Hashable` 和 `Value` 产生的。每一个类型实参必须满足它所替代的泛型形参的所有约束,包括任何 `where` 子句所指定的额外的关联类型要求。上面的例子中,类型形参 `Key` 的类型必须符合 `Hashable` 协议,因此 `String` 也必须满足 `Hashable` 协议。
-可以用本身就是泛型类型的特化版本的类型实参替代类型形参(假设已满足合适的约束和关联类型要求)。例如,为了生成一个元素类型是整型数组的数组,可以用数组的特化版本`Array`替代泛型类型`Array`的类型形参 `T` 来实现。
+可以用本身就是泛型类型的特化版本的类型实参替代类型形参(假设已满足合适的约束和关联类型要求)。例如,为了生成一个元素类型是整型数组的数组,可以用数组的特化版本 `Array` 替代泛型类型 `Array` 的类型形参 `T` 来实现。
-```
+```swift
let arrayOfArrays: Array> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```
-如[泛型形参子句](#generic_parameter)所述,不能用泛型实参子句来指定泛型函数或初始化器的类型实参。
+如 [泛型形参子句](#generic_parameter) 所述,不能用泛型实参子句来指定泛型函数或构造器的类型实参。
> 泛型实参子句语法
-> *(泛型参数子句Generic Argument Clause)* → **<** [*泛型参数列表*](GenericParametersAndArguments.html#generic_argument_list) **>**
-> *泛型参数列表* → [*泛型参数*](GenericParametersAndArguments.html#generic_argument) | [*泛型参数*](GenericParametersAndArguments.html#generic_argument) **,** [*泛型参数列表*](GenericParametersAndArguments.html#generic_argument_list)
-> *泛型参数* → [*类型*](../chapter3/03_Types.html#type)
+
+> *泛型实参子句* → **<** [*泛型实参列表*](#generic-argument-list) **>**
+
+> *泛型实参列表* → [*泛型实参*](#generic-argument) | [*泛型实参*](#generic-argument) **,** [*泛型实参列表*](#generic-argument-list)
+
+> *泛型实参* → [*类型*](03_Types.html#type)
diff --git a/source/chapter3/09_Summary_of_the_Grammar.md b/source/chapter3/09_Summary_of_the_Grammar.md
index 79988361..4377da55 100755
--- a/source/chapter3/09_Summary_of_the_Grammar.md
+++ b/source/chapter3/09_Summary_of_the_Grammar.md
@@ -239,7 +239,7 @@
> *声明* → [*构造器声明*](../chapter3/05_Declarations.html#initializer_declaration)
> *声明* → [*析构器声明*](../chapter3/05_Declarations.html#deinitializer_declaration)
> *声明* → [*扩展声明*](../chapter3/05_Declarations.html#extension_declaration)
-> *声明* → [*下标脚本声明*](../chapter3/05_Declarations.html#subscript_declaration)
+> *声明* → [*下标声明*](../chapter3/05_Declarations.html#subscript_declaration)
> *声明* → [*运算符声明*](../chapter3/05_Declarations.html#operator_declaration)
> *声明(Declarations)集* → [*声明*](../chapter3/05_Declarations.html#declaration) [*声明(Declarations)集*](../chapter3/05_Declarations.html#declarations) _可选_
@@ -373,7 +373,7 @@
> *协议成员声明* → [*协议属性声明*](../chapter3/05_Declarations.html#protocol_property_declaration)
> *协议成员声明* → [*协议方法声明*](../chapter3/05_Declarations.html#protocol_method_declaration)
> *协议成员声明* → [*协议构造器声明*](../chapter3/05_Declarations.html#protocol_initializer_declaration)
-> *协议成员声明* → [*协议下标脚本声明*](../chapter3/05_Declarations.html#protocol_subscript_declaration)
+> *协议成员声明* → [*协议下标声明*](../chapter3/05_Declarations.html#protocol_subscript_declaration)
> *协议成员声明* → [*协议关联类型声明*](../chapter3/05_Declarations.html#protocol_associated_type_declaration)
> *协议成员声明(Declarations)集* → [*协议成员声明*](../chapter3/05_Declarations.html#protocol_member_declaration) [*协议成员声明(Declarations)集*](../chapter3/05_Declarations.html#protocol_member_declarations) _可选_
@@ -394,8 +394,8 @@
-> 协议下标脚本声明语法
-> *协议下标脚本声明* → [*下标脚本头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标脚本结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter关键字(Keyword)块*](../chapter3/05_Declarations.html#getter_setter_keyword_block)
+> 协议下标声明语法
+> *协议下标声明* → [*下标头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter关键字(Keyword)块*](../chapter3/05_Declarations.html#getter_setter_keyword_block)
@@ -426,12 +426,12 @@
-> 下标脚本声明语法
-> *下标脚本声明* → [*下标脚本头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标脚本结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*代码块*](../chapter3/05_Declarations.html#code_block)
-> *下标脚本声明* → [*下标脚本头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标脚本结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter块*](../chapter3/05_Declarations.html#getter_setter_block)
-> *下标脚本声明* → [*下标脚本头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标脚本结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter关键字(Keyword)块*](../chapter3/05_Declarations.html#getter_setter_keyword_block)
-> *下标脚本头(Head)* → [*属性(Attributes)集*](../chapter3/06_Attributes.html#attributes) _可选_ [*声明修改器(declaration-modifiers)*](TODO) _可选_ **subscript** [*参数从句*](../chapter3/05_Declarations.html#parameter_clause)
-> *下标脚本结果(Result)* → **->** [*属性(Attributes)集*](../chapter3/06_Attributes.html#attributes) _可选_ [*类型*](../chapter3/03_Types.html#type)
+> 下标声明语法
+> *下标声明* → [*下标头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*代码块*](../chapter3/05_Declarations.html#code_block)
+> *下标声明* → [*下标头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter块*](../chapter3/05_Declarations.html#getter_setter_block)
+> *下标声明* → [*下标头(Head)*](../chapter3/05_Declarations.html#subscript_head) [*下标结果(Result)*](../chapter3/05_Declarations.html#subscript_result) [*getter-setter关键字(Keyword)块*](../chapter3/05_Declarations.html#getter_setter_keyword_block)
+> *下标头(Head)* → [*属性(Attributes)集*](../chapter3/06_Attributes.html#attributes) _可选_ [*声明修改器(declaration-modifiers)*](TODO) _可选_ **subscript** [*参数从句*](../chapter3/05_Declarations.html#parameter_clause)
+> *下标结果(Result)* → **->** [*属性(Attributes)集*](../chapter3/06_Attributes.html#attributes) _可选_ [*类型*](../chapter3/03_Types.html#type)
diff --git a/source/chapter3/10_Statements.md b/source/chapter3/10_Statements.md
index abd6a674..c5bcabe3 100755
--- a/source/chapter3/10_Statements.md
+++ b/source/chapter3/10_Statements.md
@@ -4,587 +4,662 @@
> 1.0
> 翻译:[coverxit](https://github.com/coverxit)
-> 校对:[numbbbbb](https://github.com/numbbbbb), [coverxit](https://github.com/coverxit), [stanzhai](https://github.com/stanzhai),
+> 校对:[numbbbbb](https://github.com/numbbbbb), [coverxit](https://github.com/coverxit), [stanzhai](https://github.com/stanzhai)
> 2.0
> 翻译+校对:[littledogboy](https://github.com/littledogboy)
+> 2.2
+> 翻译:[chenmingbiao](https://github.com/chenmingbiao)
+
+> 3.0
+> 翻译:[chenmingjia](https://github.com/chenmingjia)
+
本页包含内容:
- [循环语句](#loop_statements)
+ - [For-In 语句](#for-in_statements)
+ - [While 语句](#while_statements)
+ - [Repeat-While 语句](#repeat-while_statements)
- [分支语句](#branch_statements)
-- [带标签的语句](#labeled_statement)
-- [控制传递语句](#control_transfer_statements)
+ - [If 语句](#if_statements)
+ - [Guard 语句](#guard_statements)
+ - [Switch 语句](#switch_statements)
+- [带标签的语句](#labeled_statements)
+- [控制转移语句](#control_transfer_statements)
+ - [Break 语句](#break_statement)
+ - [Continue 语句](#continue_statement)
+ - [Fallthrough 语句](#fallthrough_statements)
+ - [Return 语句](#return_statements)
+ - [Throw 语句](#throw_statements)
+- [Defer 语句](#defer_statements)
+- [Do 语句](#do_statements)
+- [编译器控制语句](#compiler_control_statements)
+ - [编译配置语句](#build_config_statements)
+ - [行控制语句](#line_control_statements)
+- [可用性条件](#availability_condition)
-在 Swift 中,有三种类型的语句:简单语句、编译控制语句和控制流语句。简单语句是最常见的,用于构造表达式或者声明。编译控制语句允许程序改变编译器的行为以及包含构建配置和源代码控制语句。
+在 Swift 中,有三种类型的语句:简单语句、编译器控制语句和控制流语句。简单语句是最常见的,用于构造表达式或者声明。编译器控制语句允许程序改变编译器的行为,包含编译配置语句和行控制语句。
-控制流语句则用于控制程序执行的流程,Swift 中有几种类型的控制流语句:循环语句、分支语句和控制传递语句。循环语句用于重复执行代码块;分支语句用于执行满足特定条件的代码块;控制传递语句则用于修改代码的执行顺序。另外,Swift 提供了 `do` 语句来引入范围以及捕获和处理错误,还提供了 `defer` 语句在退出当前范围之前执行清理操作。
+控制流语句则用于控制程序执行的流程,Swift 中有多种类型的控制流语句:循环语句、分支语句和控制转移语句。循环语句用于重复执行代码块;分支语句用于执行满足特定条件的代码块;控制转移语句则用于改变代码的执行顺序。另外,Swift 提供了 `do` 语句,用于构建局部作用域,还用于错误的捕获和处理;还提供了 `defer` 语句,用于退出当前作用域之前执行清理操作。
-是否将分号(`;`)添加到语句的结尾处是可选的。但若要在同一行内写多条独立语句,请务必使用分号。
+是否将分号(`;`)添加到语句的末尾是可选的。但若要在同一行内写多条独立语句,则必须使用分号。
> 语句语法
-> *语句* → [*表达式*](../chapter3/04_Expressions.html#expression) **;** _可选_
-> *语句* → [*声明*](../chapter3/05_Declarations.html#declaration) **;** _可选_
-> *语句* → [*循环语句*](../chapter3/10_Statements.html#loop_statement) **;** _可选_
-> *语句* → [*分支语句*](../chapter3/10_Statements.html#branch_statement) **;** _可选_
-> *语句* → [*标记语句(Labeled Statement)*](../chapter3/10_Statements.html#labeled_statement)
-> *语句* → [*控制转移语句*](../chapter3/10_Statements.html#control_transfer_statement) **;** _可选_
-> *语句* → [*XXX语句*](../chapter3/10_Statements.html#control_transfer_statement) **;** _可选_
-> *多条语句(Statements)* → [*语句*](../chapter3/10_Statements.html#statement) [*多条语句(Statements)*](../chapter3/10_Statements.html#statements) _可选_
+
+> *语句* → [*表达式*](04_Expressions.md#expression) **;**可选
+> *语句* → [*声明*](05_Declarations.md#declaration) **;**可选
+> *语句* → [*循环语句*](#loop-statement) **;**可选
+> *语句* → [*分支语句*](#branch-statement) **;**可选
+> *语句* → [*带标签的语句*](#labeled-statement) **;**可选
+> *语句* → [*控制转移语句*](#control-transfer-statement) **;**可选
+> *语句* → [*defer 语句*](#defer-statement) **;**可选
+> *语句* → [*do 语句*](#do-statement) **:**可选
+> *语句* → [*编译器控制语句*](#compiler-control-statement)
+
+> *多条语句* → [*语句*](#statement) [*多条语句*](#statements)可选
## 循环语句
-取决于特定的循环条件,循环语句允许重复执行代码块。Swift 提供四种类型的循环语句:`for`语句、`for-in`语句、`while`语句和`do-while`语句。
+循环语句会根据特定的循环条件来重复执行代码块。Swift 提供三种类型的循环语句:`for-in` 语句、`while` 语句和 `repeat-while` 语句。
-通过`break`语句和`continue`语句可以改变循环语句的控制流。有关这两条语句,详情参见 [Break 语句](#break_statement)和 [Continue 语句](#continue_statement)。
+通过 `break` 语句和 `continue` 语句可以改变循环语句的控制流。有关这两条语句,详情参见 [Break 语句](#break_statement) 和 [Continue 语句](#continue_statement)。
> 循环语句语法
-> *循环语句* → [*for语句*](../chapter3/10_Statements.html#for_statement)
-> *循环语句* → [*for-in语句*](../chapter3/10_Statements.html#for_in_statement)
-> *循环语句* → [*while语句*](../chapter3/10_Statements.html#wheetatype类型ile_statement)
-> *循环语句* → [*do-while语句*](../chapter3/10_Statements.html#do_while_statement)
-
-
-### For 语句
-
-`for`语句只有在循环条件为真时重复执行代码块,此时计数器递增。
-
-`for`语句的形式如下:
-
-> for `initialzation`; `condition`; `increment` {
-> `statements`
-> }
-
-*initialzation*、*condition* 和 *increment* 之间的分号,以及包围循环体 *statements* 的大括号都是不可省略的。
-
-`for`语句的执行流程如下:
-
-1. *initialzation* *循环变量* 只会被执行一次,通常用于声明和初始化在接下来的循环中需要使用的变量。
-2. 判断 *condition* 循环条件:
- 如果为`true`,*statements* *循环体* 将会被执行,然后转到第3步。如果为`false`,*statements* 和 *increment* *循环增量* 都不会被执行,`for`至此执行完毕。
-3. 计算 *increment* 表达式,然后转到第2步。
-
-在 *initialzation* 中定义的变量仅在`for`循环的作用域内有效。*condition* 表达式的值的类型必须遵循`BooleanType `协议。
-
-> For 循环语法
-> *for语句* → **for** [*for初始条件*](../chapter3/10_Statements.html#for_init) _可选_ **;** [*表达式*](../chapter3/04_Expressions.html#expression) _可选_ **;** [*表达式*](../chapter3/04_Expressions.html#expression) _可选_ [*代码块*](../chapter3/05_Declarations.html#code_block)
-> *for语句* → **for** **(** [*for初始条件*](../chapter3/10_Statements.html#for_init) _可选_ **;** [*表达式*](../chapter3/04_Expressions.html#expression) _可选_ **;** [*表达式*](../chapter3/04_Expressions.html#expression) _可选_ **)** [*代码块*](../chapter3/05_Declarations.html#code_block)
-> *for初始条件* → [*变量声明*](../chapter3/05_Declarations.html#variable_declaration) | [*表达式列表*](../chapter3/04_Expressions.html#expression_list)
-
+
+> *循环语句* → [*for-in 语句*](#for-in-statement)
+> *循环语句* → [*while 语句*](#while-statement)
+> *循环语句* → [*repeat-while 语句*](#repeat-while-statement)
### For-In 语句
-`for-in`语句允许在重复执行代码块的同时,迭代集合(或遵循`Sequence`协议的任意类型)中的每一项。
+`for-in` 语句会为集合(或实现了 `SequenceType` 协议的任意类型)中的每一项执行一次代码块。
-`for-in`语句的形式如下:
+`for-in` 语句的形式如下:
-> for `item` in `collection` {
-> `statements`
-> }
+```swift
+for 项 in 集合 {
+ 循环体语句
+}
+```
-`for-in`语句在循环开始前会调用 *collection* 表达式的`generate`方法来获取一个生成器类型(这是一个遵循`Generator`协议的类型)的值。接下来循环开始,调用 *collection* 表达式的`next`方法。如果其返回值不是`None`,它将会被赋给 *item*,然后执行 *statements*,执行完毕后回到循环开始处;否则,将不会赋值给 *item* 也不会执行 *statements*,`for-in`至此执行完毕。
-
-> For-In 循环语法
-> *for-in语句* → **for** [*模式*](../chapter3/07_Patterns.html#pattern) **in** [*表达式*](../chapter3/04_Expressions.html#expression) [*代码块*](../chapter3/05_Declarations.html#code_block)
+`for-in` 语句在循环开始前会调用集合表达式的 `generate()` 方法来获取一个实现了 `GeneratorType` 协议的类型的值。接下来循环开始,反复调用该值的 `next()` 方法。如果其返回值不是 `None`,它将会被赋给“项”,然后执行循环体语句,执行完毕后回到循环开始处,继续重复这一过程;否则,既不会赋值也不会执行循环体语句,`for-in` 语句至此执行完毕。
+> for-in 语句语法
+
+> *for-in 语句* → **for** **case**可选 [*模式*](07_Patterns.md#pattern) **in** [*表达式*](04_Expressions.md#expression) [*where子句*](#where-clause)可选 [*代码块*](05_Declarations.md#code-block)
### While 语句
-`while`语句当循环条件为真时,允许重复执行代码块。
+只要循环条件为真,`while` 语句就会重复执行代码块。
-`while`语句的形式如下:
+`while` 语句的形式如下:
-> while `condition` {
-> `statements`
-> }
+```swift
+while 条件 {
+ 语句
+}
+```
-`while`语句的执行流程如下:
+`while` 语句的执行流程如下:
-1. 计算 *condition* 表达式:
- 如果为真`true`,转到第2步。如果为`false`,`while`至此执行完毕。
-2. 执行 *statements* ,然后转到第1步。
+1. 判断条件的值。如果为 `true`,转到第 2 步;如果为 `false`,`while` 语句至此执行完毕。
+2. 执行循环体中的语句,然后重复第 1 步。
-由于 *condition* 的值在 *statements* 执行前就已计算出,因此`while`语句中的 *statements* 可能会被执行若干次,也可能不会被执行。
+由于会在执行循环体中的语句前判断条件的值,因此循环体中的语句可能会被执行若干次,也可能一次也不会被执行。
-*condition* 表达式的值的类型必须遵循`BooleanType `协议。同时,*condition* 表达式也可以使用可选绑定,详情参见[可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
+条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
-> While 循环语法
-> *while语句* → **while** [*while条件*](../chapter3/10_Statements.html#while_condition) [*代码块*](../chapter3/05_Declarations.html#code_block)
-> *条件* → [*表达式*](../chapter3/04_Expressions.html#expression) | [*声明*](../chapter3/05_Declarations.html#declaration)
-> *条件* → [*表达式*](../chapter3/04_Expressions.html#expression)
-> *条件* → [*表达式*](../chapter3/04_Expressions.html#expression) | [*条件列表*](TODO)
-> *条件* → [*可用条件*](../chapter3/10_Statement.html#availability) [*表达式*](../chapter3/04_Expressions.html#expression)
-> *条件列表* → [*条件条件*](TODO) [*条件列表*](TODO)
-> *条件* → [*可用条件*](../chapter3/10_Statement.html#availability) [可选绑定条件](../chapter2/01_The_Basics.html#optional_binding)
-> *case条件* → **case** [*模式*](../chapter3/07_Patterns.html#pattern) [构造器](TODO) [where](DOTO)
-> *可选绑定条件* → [可选绑定头](TODO) [持续可选绑定](TODO) [持续可选绑定列表](TODO)
-> *可选绑定头* → **let** [*模式*](../chapter3/07_Patterns.html#pattern) [构造器](TODO) **var** [*模式*](../chapter3/07_Patterns.html#pattern) [构造器](TODO)
-> *可持续绑定列表* → [*模式*](../chapter3/07_Patterns.html#pattern) | [构造器](TODO) [可选绑定头](TODO)
->
+> while 语句语法
+
+
+> *while 语句* → **while** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block)
+
+
+> *条件子句* → [*表达式*](04_Expressions.md#expression)
+> *条件子句* → [*表达式*](04_Expressions.md#expression) **,** [*条件列表*](#condition-list)
+> *条件子句* → [*条件列表*](#condition-list)
+> *条件子句* → [*可用性条件*](#availability-condition) **,** [*表达式*](04_Expressions.md#expression)
+
+
+> *条件列表* → [*条件*](#condition) | [*条件*](#condition) **,** [*条件列表*](#condition-list)
+
+> *条件* → [*表达式*](04_Expressions.md#expression) |[*可用性条件*](#availability-condition) | [*case条件*](#case-condition) | [*可选绑定条件*](#optional-binding-condition)
+
+> *case 条件* → **case** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer)
+
+
+> *可选绑定条件* → **let** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer) | **var** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer)
-
-
+
### Repeat-While 语句
-`repeat-while`语句允许代码块被执行一次或多次。
+`repeat-while` 语句至少执行一次代码块,之后只要循环条件为真,就会重复执行代码块。
-`repeat-while`语句的形式如下:
+`repeat-while` 语句的形式如下:
-> repeat {
-> `statements`
-> } while `condition`
+```swift
+repeat {
+ 语句
+} while 条件
+```
-`repeat-while`语句的执行流程如下:
+`repeat-while` 语句的执行流程如下:
-1. 执行 *statements*,然后转到第2步。
-2. 计算 *condition* 表达式:
- 如果为`true`,转到第1步。如果为`false`,`repeat-while`至此执行完毕。
+1. 执行循环体中的语句,然后转到第 2 步。
+2. 判断条件的值。如果为 `true`,重复第 1 步;如果为 `false`,`repeat-while` 语句至此执行完毕。
-由于 *condition* 表达式的值是在 *statements* 执行后才计算出,因此`repeat-while`语句中的 *statements* 至少会被执行一次。
+由于条件的值是在循环体中的语句执行后才进行判断,因此循环体中的语句至少会被执行一次。
-*condition* 表达式的值的类型必须遵循`BooleanType `协议。同时,*condition* 表达式也可以使用可选绑定,详情参见[可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
+条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
-> Repeat-While 循环语法
-> * repeat-while语句* → **repeat** [*代码块*](../chapter3/05_Declarations.html#code_block) **while** [*while条件*](../chapter3/10_Statements.html#while_condition)
+> repeat-while 语句语法
+
+> *repeat-while 语句* → **repeat** [*代码块*](05_Declarations.md#code-block) **while** [*表达式*](04_Expressions.md#expression)
## 分支语句
-取决于一个或者多个条件的值,分支语句允许程序执行指定部分的代码。显然,分支语句中条件的值将会决定如何分支以及执行哪一块代码。Swift 提供两种类型的分支语句:`if`语句和`switch`语句。
+分支语句会根据一个或者多个条件来执行指定部分的代码。分支语句中的条件将会决定程序如何分支以及执行哪部分代码。Swift 提供两种类型的分支语句:`if` 语句和 `switch` 语句。
-`switch`语句中的控制流可以用`break`语句修改,详情请见[Break 语句](#break_statement)。
+`if` 语句和 `switch` 语句中的控制流可以用 `break` 语句改变,请参阅 [Break 语句](#break_statement)。
> 分支语句语法
-> *分支语句* → [*if语句*](../chapter3/10_Statements.html#if_statement)
-> *分支语句* → [*switch语句*](../chapter3/10_Statements.html#switch_statement)
-
+
+> *分支语句* → [*if 语句*](#if-statement)
+> *分支语句* → [*guard 语句*](#guard-statement)
+> *分支语句* → [*switch 语句*](#switch-statement)
### If 语句
-取决于一个或多个条件的值,`if`语句将决定执行哪一块代码。
+`if` 语句会根据一个或多个条件来决定执行哪一块代码。
-`if`语句有两种标准形式,在这两种形式里都必须有大括号。
+`if` 语句有两种基本形式,无论哪种形式,都必须有花括号。
第一种形式是当且仅当条件为真时执行代码,像下面这样:
-> if `condition` {
-> `statements`
-> }
+```swift
+if 条件 {
+ 语句
+}
+```
-第二种形式是在第一种形式的基础上添加 *else 语句*,当只有一个 else 语句时,像下面这样:
+第二种形式是在第一种形式的基础上添加 `else` 语句,当只有一个 `else` 语句时,像下面这样:
-> if `condition` {
-> `statements to execute if condition is true`
-> } else {
-> `statements to execute if condition is false`
-> }
+```swift
+if 条件 {
+ 若条件为真则执行这部分语句
+} else {
+ 若条件为假则执行这部分语句
+}
+```
-同时,else 语句也可包含`if`语句,从而形成一条链来测试更多的条件,像下面这样:
+`else` 语句也可包含 `if` 语句,从而形成一条链来测试更多的条件,像下面这样:
-> if `condition 1` {
-> `statements to execute if condition 1 is true`
-> } else if `condition 2` {
-> `statements to execute if condition 2 is true`
-> }
-> else {
-> `statements to execute if both conditions are false`
-> }
+```swift
+if 条件1 {
+ 若条件1为真则执行这部分语句
+} else if 条件2 {
+ 若条件2为真则执行这部分语句
+} else {
+ 若前两个条件均为假则执行这部分语句
+}
+```
-`if`语句中条件的值的类型必须遵循`LogicValue`协议。同时,条件也可以使用可选绑定,详情参见[可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
-
-> If语句语法
-> *if语句* → **if** [*if条件*](../chapter3/10_Statements.html#if_condition) [*代码块*](../chapter3/05_Declarations.html#code_block) [*else(Clause)*](../chapter3/10_Statements.html#else_clause) _可选_
-> *if条件* → [*表达式*](../chapter3/04_Expressions.html#expression) | [*声明*](../chapter3/05_Declarations.html#declaration)
-> *else(Clause)* → **else** [*代码块*](../chapter3/05_Declarations.html#code_block) | **else** [*if语句*](../chapter3/10_Statements.html#if_statement)
+`if` 语句中条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
+> if 语句语法
+
+> *if 语句* → **if** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block) [*else子句*](#else-clause)可选
+
+> *else 子句* → **else** [*代码块*](05_Declarations.md#code-block) | **else** [*if语句*](#if-statement)
### Guard 语句
-`guard` 语句用来转移程序控制出其作用域,如果一个或者多个条件不成立。
- `guard` 语句的格式如下:
- > guard `condition` else {
- `statements`
- >}
+如果一个或者多个条件不成立,可用 `guard` 语句用来退出当前作用域。
+
+`guard` 语句的格式如下:
+
+```swift
+guard 条件 else {
+ 语句
+}
+```
+
+`guard` 语句中条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件也可以是一条可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
- `guard`语句中条件值的类型必须遵循`LogicValue`协议。且条件可以使用可选绑定,详情参见[可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
+在 `guard` 语句中进行可选绑定的常量或者变量,其可用范围从声明开始直到作用域结束。
- 在`guard`语句中声明的常量或者变量,可用范围从声明开始到作用域结束,常量和变量的值从可选绑定声明中分配。
-
- `guard`语句需要有`else`子句,并且必须调用被`noreturn`属性标记的函数,或者使用下面的语句把程序执行转移到guard语句的作用域外。
+`guard` 语句必须有 `else` 子句,而且必须在该子句中调用标记 `noreturn` 特性的函数,或者使用下面的语句退出当前作用域:
* `return`
* `break`
* `continue`
* `throw`
-执行转移语句详情参见[控制传递语句](TODO)
+关于控制转移语句,请参阅 [控制转移语句](#control_transfer_statements)。
+> guard 语句语法
+
+> *guard 语句* → **guard** [*条件子句*](#condition-clause) **else** [*代码块*](05_Declarations.html#code-block)
### Switch 语句
-取决于`switch`语句的*控制表达式(control expression)*,`switch`语句将决定执行哪一块代码。
+`switch` 语句会根据控制表达式的值来决定执行哪部分代码。
-`switch`语句的形式如下:
+`switch` 语句的形式如下:
-> switch `control expression` {
-> case `pattern 1`:
-> `statements`
-> case `pattern 2` where `condition`:
-> `statements`
-> case `pattern 3` where `condition`,
-> `pattern 4` where `condition`:
-> `statements`
-> default:
-> `statements`
-> }
+```swift
+switch 控制表达式 {
+case 模式1:
+ 语句
+case 模式2 where 条件:
+ 语句
+case 模式3 where 条件, 模式4 where 条件:
+ 语句
+default:
+ 语句
+}
+```
-`switch`语句的*控制表达式(control expression)*会首先被计算,然后与每一个 case 的模式(pattern)进行匹配。如果匹配成功,程序将会执行对应的 case 分支里的 *statements*。另外,每一个 case 分支都不能为空,也就是说在每一个 case 分支中至少有一条语句。如果你不想在匹配到的 case 分支中执行代码,只需在该分支里写一条`break`语句即可。
+`switch` 语句会先计算控制表达式的值,然后与每一个 `case` 的模式进行匹配。如果匹配成功,程序将会执行对应的 `case` 中的语句。另外,每一个 `case` 都不能为空,也就是说在每一个 `case` 中必须至少有一条语句。如果你不想在匹配到的 `case` 中执行代码,只需在该 `case` 中写一条 `break` 语句即可。
-可以用作控制表达式的值是十分灵活的,除了标量类型(scalar types,如`Int`、`Character`)外,你可以使用任何类型的值,包括浮点数、字符串、元组、自定义类的实例和可选(optional)类型,甚至是枚举类型中的成员值和指定的范围(range)等。关于在`switch`语句中使用这些类型,详情参见[控制流](../chapter2/05_Control_Flow.html)一章的 [Switch](../chapter2/05_Control_Flow.html#switch)。
+可以用作控制表达式的值是十分灵活的。除了标量类型外,如 `Int`、`Character`,你可以使用任何类型的值,包括浮点数、字符串、元组、自定义类型的实例和可选类型。控制表达式的值还可以用来匹配枚举类型中的成员值或是检查该值是否包含在指定的 `Range` 中。关于如何在 `switch` 语句中使用这些类型,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章中的 [Switch](../chapter2/05_Control_Flow.html#switch)。
-你可以在模式后面添加一个起保护作用的表达式(guard expression)。*起保护作用的表达式*是这样构成的:关键字`where`后面跟着一个作为额外测试条件的表达式。因此,当且仅当*控制表达式*匹配一个*case*的某个模式且起保护作用的表达式为真时,对应 case 分支中的 *statements* 才会被执行。在下面的例子中,*控制表达式*只会匹配含两个相等元素的元组,如`(1, 1)`:
+每个 `case` 的模式后面可以有一个 `where` 子句。`where` 子句由 `where` 关键字紧跟一个提供额外条件的表达式组成。因此,当且仅当控制表达式匹配一个 `case` 的模式且 `where` 子句的表达式为真时,`case` 中的语句才会被执行。在下面的例子中,控制表达式只会匹配包含两个相等元素的元组,例如 `(1, 1)`:
```swift
case let (x, y) where x == y:
```
-正如上面这个例子,也可以在模式中使用`let`(或`var`)语句来绑定常量(或变量)。这些常量(或变量)可以在其对应的起保护作用的表达式和其对应的*case*块里的代码中引用。但是,如果 case 中有多个模式匹配控制表达式,那么这些模式都不能绑定常量(或变量)。
+正如上面这个例子,也可以在模式中使用 `let`(或 `var`)语句来绑定常量(或变量)。这些常量(或变量)可以在对应的 `where` 子句以及 `case` 中的代码中使用。但是,如果一个 `case` 中含有多个模式,所有的模式必须包含相同的常量(或变量)绑定,并且每一个绑定的常量(或变量)必须在所有的条件模式中都有相同的类型。
-`switch`语句也可以包含默认(`default`)分支,只有其它 case 分支都无法匹配控制表达式时,默认分支中的代码才会被执行。一个`switch`语句只能有一个默认分支,而且必须在`switch`语句的最后面。
+`switch` 语句也可以包含默认分支,使用 `default` 关键字表示。只有所有 `case` 都无法匹配控制表达式时,默认分支中的代码才会被执行。一个 `switch` 语句只能有一个默认分支,而且必须在 `switch` 语句的最后面。
-尽管模式匹配操作实际的执行顺序,特别是模式的计算顺序是不可知的,但是 Swift 规定`switch`语句中的模式匹配的顺序和书写源代码的顺序保持一致。因此,当多个模式含有相同的值且能够匹配控制表达式时,程序只会执行源代码中第一个匹配的 case 分支中的代码。
+`switch` 语句中 `case` 的匹配顺序和源代码中的书写顺序保持一致。因此,当多个模式都能匹配控制表达式时,只有第一个匹配的 `case` 中的代码会被执行。
-#### Switch 语句必须是完备的
+#### Switch 语句不能有遗漏
-在 Swift 中,`switch`语句中控制表达式的每一个可能的值都必须至少有一个 case 分支与之对应。在某些情况下(例如,表达式的类型是`Int`),你可以使用默认块满足该要求。
+在 Swift 中,`switch` 语句中控制表达式的每一个可能的值都必须至少有一个 `case` 与之对应。在某些无法面面俱到的情况下(例如,表达式的类型是 `Int`),你可以使用 `default` 分支满足该要求。
-#### 不存在隐式的贯穿(fall through)
+#### 不存在隐式落入
-当匹配的 case 分支中的代码执行完毕后,程序会终止`switch`语句,而不会继续执行下一个 case 分支。这就意味着,如果你想执行下一个 case 分支,需要显式地在你需要的 case 分支里使用`fallthrough`语句。关于`fallthrough`语句的更多信息,详情参见 [Fallthrough 语句](#fallthrough_statement)。
+当匹配到的 `case` 中的代码执行完毕后,`switch` 语句会直接退出,而不会继续执行下一个 `case` 。这就意味着,如果你想执行下一个 `case`,需要显式地在当前 `case` 中使用 `fallthrough` 语句。关于 `fallthrough` 语句的更多信息,请参阅 [Fallthrough 语句](#fallthrough_statements)。
-> Switch语句语法
-> *switch语句* → **switch** [*表达式*](../chapter3/04_Expressions.html#expression) **{** [*SwitchCase列表*](../chapter3/10_Statements.html#switch_cases) _可选_ **}**
-> *SwitchCase列表* → [*SwitchCase*](../chapter3/10_Statements.html#switch_case) [*SwitchCase列表*](../chapter3/10_Statements.html#switch_cases) _可选_
-> *SwitchCase* → [*case标签*](../chapter3/10_Statements.html#case_label) [*多条语句(Statements)*](../chapter3/10_Statements.html#statements) | [*default标签*](../chapter3/10_Statements.html#default_label) [*多条语句(Statements)*](../chapter3/10_Statements.html#statements)
-> *SwitchCase* → [*case标签*](../chapter3/10_Statements.html#case_label) **;** | [*default标签*](../chapter3/10_Statements.html#default_label) **;**
-> *case标签* → **case** [*case项列表*](../chapter3/10_Statements.html#case_item_list) **:**
-> *case项列表* → [*模式*](../chapter3/07_Patterns.html#pattern) [*guard-clause*](../chapter3/10_Statements.html#guard_clause) _可选_ | [*模式*](../chapter3/07_Patterns.html#pattern) [*guard-clause*](../chapter3/10_Statements.html#guard_clause) _可选_ **,** [*case项列表*](../chapter3/10_Statements.html#case_item_list)
-> *default标签* → **default** **:**
-> *where-clause* → **where** [*guard-expression*](../chapter3/10_Statements.html#guard)
-> *where-expression* → [*表达式*](../chapter3/04_Expressions.html#expression)
+> switch 语句语法
+
+
+> *switch 语句* → **switch** [*表达式*](04_Expressions.md#expression) **{** [*switch-case列表*](#switch-cases)可选 **}**
+
+> *switch case 列表* → [*switch-case*](#switch-case) [*switch-case列表*](#switch-cases)可选
+
+> *switch case* → [*case标签*](#case-label) [*多条语句*](#statements) | [*default标签*](#default-label) [*多条语句*](#statements)
+
+
+> *case 标签* → **case** [*case项列表*](#case-item-list) **:**
+
+> *case 项列表* → [*模式*](07_Patterns.md#pattern) [*where子句*](#where-clause)可选 | [*模式*](07_Patterns.md#pattern) [*where子句*](#where-clause)可选 **,** [*case项列表*](#case-item-list)
+
+> *default 标签* → **default** **:**
+
+
+> *where-clause* → **where** [*where表达式*](#where-expression)
+
+> *where-expression* → [*表达式*](04_Expressions.md#expression)
-
## 带标签的语句
-你可以在循环语句或`switch`语句前面加上*标签*,它由标签名和紧随其后的冒号(:)组成。在`break`和`continue`后面跟上标签名可以显式地在循环语句或`switch`语句中更改控制流,把控制权传递给指定标签标记的语句。关于这两条语句用法,详情参见 [Break 语句](#break_statement)和 [Continue 语句](#continue_statement)。
+你可以在循环语句或 `switch` 语句前面加上标签,它由标签名和紧随其后的冒号(`:`)组成。在 `break` 和 `continue` 后面跟上标签名可以显式地在循环语句或 `switch` 语句中改变相应的控制流。关于这两条语句用法,请参阅 [Break 语句](#break_statement) 和 [Continue 语句](#continue_statement)。
-标签的作用域是该标签所标记的语句之后的所有语句。你可以不使用带标签的语句,但只要使用它,标签名就必唯一。
+标签的作用域在该标签所标记的语句内。可以嵌套使用带标签的语句,但标签名必须唯一。
-关于使用带标签的语句的例子,详情参见[控制流](../chapter2/05_Control_Flow.html)一章的[带标签的语句](../chapter2/05_Control_Flow.html#labeled_statements)。
+关于使用带标签的语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章中的 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
-> 标记语句语法
-> *标记语句(Labeled Statement)* → [*语句标签*](../chapter3/10_Statements.html#statement_label) [*循环语句*](../chapter3/10_Statements.html#loop_statement) | [*语句标签*](../chapter3/10_Statements.html#statement_label) [*switch语句*](../chapter3/10_Statements.html#switch_statement)
-> *语句标签* → [*标签名称*](../chapter3/10_Statements.html#label_name) **:**
-> *标签名称* → [*标识符*](../chapter3/02_Lexical_Structure.html#identifier)
+> 带标签的语句语法
+
+> *带标签的语句* → [*语句标签*](#statement-label) [*循环语句*](#loop-statement) | [*语句标签*](#statement-label) [*if语句*](#if-statement) | [*语句标签*](#statement-label) [*switch语句*](#switch-statement)
+
+> *语句标签* → [*标签名称*](#label-name) **:**
+
+> *标签名称* → [*标识符*](02_Lexical_Structure.md#identifier)
-## 控制传递语句
+## 控制转移语句
-通过无条件地把控制权从一片代码传递到另一片代码,控制传递语句能够改变代码执行的顺序。Swift 提供四种类型的控制传递语句:`break`语句、`continue`语句、`fallthrough`语句和`return`语句。
+控制转移语句能够无条件地把控制权从一片代码转移到另一片代码,从而改变代码执行的顺序。Swift 提供五种类型的控制转移语句:`break` 语句、`continue` 语句、`fallthrough` 语句、`return` 语句和 `throw` 语句。
-> 控制传递语句(Control Transfer Statement) 语法
-> *控制传递语句* → [*break语句*](../chapter3/10_Statements.html#break_statement)
-> *控制传递语句* → [*continue语句*](../chapter3/10_Statements.html#continue_statement)
-> *控制传递语句* → [*fallthrough语句*](../chapter3/10_Statements.html#fallthrough_statement)
-> *控制传递语句* → [*return语句*](../chapter3/10_Statements.html#return_statement)
-> *控制传递语句* → [*throw语句*](../chapter3/10_Statements.html#throw_statement)
+> 控制转移语句语法
+
+> *控制转移语句* → [*break 语句*](#break-statement)
+> *控制转移语句* → [*continue 语句*](#continue-statement)
+> *控制转移语句* → [*fallthrough 语句*](#fallthrough-statement)
+> *控制转移语句* → [*return 语句*](#return-statement)
+> *控制转移语句* → [*throw 语句*](#throw-statement)
-
+
### Break 语句
-`break`语句用于终止循环或`switch`语句的执行。使用`break`语句时,可以只写`break`这个关键词,也可以在`break`后面跟上标签名(label name),像下面这样:
+`break` 语句用于终止循环语句、`if` 语句或 `switch` 语句的执行。使用 `break` 语句时,可以只写 `break` 这个关键词,也可以在 `break` 后面跟上标签名,像下面这样:
> break
-> break `label name`
+> break `标签名`
-当`break`语句后面带标签名时,可用于终止由这个标签标记的循环或`switch`语句的执行。
+当 `break` 语句后面带标签名时,可用于终止由这个标签标记的循环语句、`if` 语句或 `switch` 语句的执行。
-而当只写`break`时,则会终止`switch`语句或上下文中包含`break`语句的最内层循环的执行。
+而只写 `break` 时,则会终止 `switch` 语句或 `break` 语句所属的最内层循环语句的执行。不能使用 `break` 语句来终止未使用标签的 `if` 语句。
-在这两种情况下,控制权都会被传递给循环或`switch`语句外面的第一行语句。
+无论哪种情况,控制权都会被转移给被终止的控制流语句后面的第一行语句。
-关于使用`break`语句的例子,详情参见[控制流](../chapter2/05_Control_Flow.html)一章的 [Break](../chapter2/05_Control_Flow.html#break) 和[带标签的语句](../chapter2/05_Control_Flow.html#labeled_statements)。
+关于使用 `break` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [Break](../chapter2/05_Control_Flow.md#break) 和 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
-> Break 语句语法
-> *break语句* → **break** [*标签名称*](../chapter3/10_Statements.html#label_name) _可选_
+> break 语句语法
+
+> *break 语句* → **break** [*标签名称*](#label-name)可选
-
+
### Continue 语句
-`continue`语句用于终止循环中当前迭代的执行,但不会终止该循环的执行。使用`continue`语句时,可以只写`continue`这个关键词,也可以在`continue`后面跟上标签名(label name),像下面这样:
+`continue` 语句用于终止循环中当前迭代的执行,但不会终止该循环的执行。使用 `continue` 语句时,可以只写 `continue` 这个关键词,也可以在 `continue` 后面跟上标签名,像下面这样:
> continue
-> continue `label name`
+> continue `标签名`
-当`continue`语句后面带标签名时,可用于终止由这个标签标记的循环中当前迭代的执行。
+当 `continue` 语句后面带标签名时,可用于终止由这个标签标记的循环中当前迭代的执行。
-而当只写`break`时,可用于终止上下文中包含`continue`语句的最内层循环中当前迭代的执行。
+而当只写 `continue` 时,可用于终止 `continue` 语句所属的最内层循环中当前迭代的执行。
-在这两种情况下,控制权都会被传递给循环外面的第一行语句。
+在这两种情况下,控制权都会被转移给循环语句的条件语句。
-在`for`语句中,`continue`语句执行后,*increment* 表达式还是会被计算,这是因为每次循环体执行完毕后 *increment* 表达式都会被计算。
+在 `for` 语句中,`continue` 语句执行后,增量表达式还是会被计算,这是因为每次循环体执行完毕后,增量表达式都会被计算。
-关于使用`continue`语句的例子,详情参见[控制流](../chapter2/05_Control_Flow.html)一章的 [Continue](../chapter2/05_Control_Flow.html#continue) 和[带标签的语句](../chapter2/05_Control_Flow.html#labeled_statements)。
+关于使用 `continue` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [Continue](../chapter2/05_Control_Flow.md#continue) 和 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
-> Continue 语句语法
-> *continue语句* → **continue** [*标签名称*](../chapter3/10_Statements.html#label_name) _可选_
+> continue 语句语法
+
+> *continue 语句* → **continue** [*标签名称*](#label-name)可选
### Fallthrough 语句
-`fallthrough`语句用于在`switch`语句中传递控制权。`fallthrough`语句会把控制权从`switch`语句中的一个 case 传递给下一个 case 。这种传递是无条件的,即使下一个 case 的模式与`switch`语句的控制表达式的值不匹配。
+`fallthrough` 语句用于在 `switch` 语句中转移控制权。`fallthrough` 语句会把控制权从 `switch` 语句中的一个 `case` 转移到下一个 `case`。这种控制权转移是无条件的,即使下一个 `case` 的模式与 `switch` 语句的控制表达式的值不匹配。
-`fallthrough`语句可出现在`switch`语句中的任意 case 里,但不能出现在最后一个 case 分支中。同时,`fallthrough`语句也不能把控制权传递给使用了可选绑定的 case 分支。
+`fallthrough` 语句可出现在 `switch` 语句中的任意 `case` 中,但不能出现在最后一个 `case` 中。同时,`fallthrough` 语句也不能把控制权转移到使用了值绑定的 `case`。
-关于在`switch`语句中使用`fallthrough`语句的例子,详情参见[控制流](../chapter2/05_Control_Flow.html)一章的[控制传递语句](../chapter2/05_Control_Flow.html#control_transfer_statements)。
+关于在 `switch` 语句中使用 `fallthrough` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [控制转移语句](../chapter2/05_Control_Flow.md#control_transfer_statements)。
-> Fallthrough 语句语法
-> *fallthrough语句* → **fallthrough**
+> fallthrough 语句语法
+
+> *fallthrough 语句* → **fallthrough**
### Return 语句
-`return`语句用于在函数或方法的实现中将控制权传递给调用者,接着程序将会从调用者的位置继续向下执行。
+`return` 语句用于在函数或方法的实现中将控制权转移到调用函数或方法,接着程序将会从调用位置继续向下执行。
-使用`return`语句时,可以只写`return`这个关键词,也可以在`return`后面跟上表达式,像下面这样:
+使用 `return` 语句时,可以只写 `return` 这个关键词,也可以在 `return` 后面跟上表达式,像下面这样:
> return
-> return `expression`
+> return `表达式`
-当`return`语句后面带表达式时,表达式的值将会返回给调用者。如果表达式值的类型与调用者期望的类型不匹配,Swift 则会在返回表达式的值之前将表达式值的类型转换为调用者期望的类型。
+当 `return` 语句后面带表达式时,表达式的值将会返回给调用函数或方法。如果表达式的值的类型与函数或者方法声明的返回类型不匹配,Swift 则会在返回表达式的值之前将表达式的值的类型转换为返回类型。
-而当只写`return`时,仅仅是将控制权从该函数或方法传递给调用者,而不返回一个值。(这就是说,该函数或方法的返回类型为`Void`或`()`)
+> 注意
+> 正如 [可失败构造器](05_Declarations.md#failable_initializers) 中所描述的,`return nil` 在可失败构造器中用于表明构造失败。
-> Return 语句语法
-> *return语句* → **return** [*表达式*](../chapter3/04_Expressions.html#expression) _可选_
+而只写 `return` 时,仅仅是从该函数或方法中返回,而不返回任何值(也就是说,函数或方法的返回类型为 `Void` 或者说 `()`)。
-
-### Availability 语句
-
-可用性条件,被当做`if` ,`while` 语句的条件,并且 `guard` 语句在运行时会基于特定的语法格式查询接口的可用性。
-
-avaliability 语句的形式如下:
-> if #available(`platform name version`,` ...`, *) {
-> `statements to execute if the APIs are available`
-> } else {
-> `fallback statements to execute if the APIs are unavailable`
-> }
-
-可用性条件执行一个代码块时,取决于在运行时想要使用的接口是否可用。
-当编译器检查到代码块中的接口是可用的,则从可用性条件中获取相应信息。
-
-可用性条件使用逗号分隔平台名称和版本列表。使用`iOS`,`OSX`,以及`watchOS`为平台名称,包括相应的版本号。*参数是必需的。在任何平台上代码块主体都被可用性条件保护起来,由满足最低部署条件的目标设备运行。
-
-与布尔类型条件不同,不能用逻辑运算符 **&&** 和 **||** 合并可用性条件。
-
-> 可用性条件语法
-> *可用性条件* → **#available** ( [availability-arguments](TODO) )
-> *可用性条件* → [availability-argument](TODO) | [availability-argument](TODO) , [availability-arguments](TODO)
-> *可用性条件* → [平台名称](TODO) [版本号](TODO)
-> *可用性条件* → **\***
-> *平台名称* → **iOS** | **iOSApplicationExtension**
-> *平台名称* → **OSX** | **OSXApplicationExtension**
-> *平台名称* → **watchOS**
-> *版本号* → [十进制数字](TODO)
-> *版本号* → [十进制数字](TODO) **.** [十进制数字](TODO)
-> *版本号* → [十进制数字](TODO) **.** [十进制数字](TODO) **.** [十进制数字](TODO)
+> return 语句语法
+
+> *return 语句* → **return** [*表达式*](04_Expressions.html#expression)可选
-
### Throw 语句
-`throw`语句出现在抛出函数或者抛出方法体内,或者类型被`throws`关键字标记的表达式体内。
+
+`throw` 语句出现在抛出函数或者抛出方法体内,或者类型被 `throws` 关键字标记的闭包表达式体内。
-`throw`语句使程序结束执行当前的作用域,并在封闭作用域中传播错误。抛出的错误会一直传播,直到被`do`语句的`catch`子句处理掉。
+`throw` 语句使程序在当前作用域结束执行,并向外围作用域传播错误。抛出的错误会一直传递,直到被 `do` 语句的 `catch` 子句处理掉。
-`throw`语句由`throw`关键字 跟一个表达式组成 ,如下所示。
+`throw` 语句由 `throw` 关键字紧跟一个表达式组成,如下所示:
-> throw `expression`
+> throw `表达式`
-表达式值的类型必须遵循 `LogicValue`协议
+表达式的结果必须符合 `ErrorType` 协议。
-关于如何使用`throw`语句的例子,详情参见[错误处理](TODO)一章的[抛出错误](TODO)。
+关于如何使用 `throw` 语句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md) 一章的 [用 throwing 函数传递错误](../chapter2/18_Error_Handling.md#propagating_errors_using_throwing_functions)。
> throw 语句语法
-> *抛出语句* → **throw** *[表达式](TODO)*
+
+> *throw 语句* → **throw** [*表达式*](04_Expressions.md#expression)
-### Defer 语句
+## Defer 语句
- `defer` 语句用于转移程序控制出延迟语句作用域之前执行代码。
-
-在 `defer` 语句中的语句无论程序控制如何转移都会执行。这意味着 `defer` 语句可以被使用在以下这些情况,像手动得执行资源管理,关闭文件描述,或者即使抛出了错误也需要去实现执行一些动作。
+`defer` 语句用于在退出当前作用域之前执行代码。
-如果多个 `defer` 语句出现在同一范围内,那么它们执行的顺序与出现的顺序相反。给定作用域中的第一个`defer` 语句,会在最后执行,这意味着最后执行的延迟语句中的语句涉及的资源可以被其他 `defer`语句清理掉。
+`defer` 语句形式如下:
-> 1 func f( ) {
-> 2 defer { print("First") }
-> 3 defer { print("Second") }
-> 4 defer { print("Third") }
-> 5 }
-> 6 f()
-> 7 // prints "Third"
-> 8 // prints "Second"
-> 9 // prints "First"
+```swift
+defer {
+ 语句
+}
+```
+在 `defer` 语句中的语句无论程序控制如何转移都会被执行。在某些情况下,例如,手动管理资源时,比如关闭文件描述符,或者即使抛出了错误也需要执行一些操作时,就可以使用 `defer` 语句。
-`defer` 语句中的语句无法转移程序控制出延迟语句。
+如果多个 `defer` 语句出现在同一作用域内,那么它们执行的顺序与出现的顺序相反。给定作用域中的第一个 `defer` 语句,会在最后执行,这意味着代码中最靠后的 `defer` 语句中引用的资源可以被其他 `defer` 语句清理掉。
+
+```swift
+func f() {
+ defer { print("First") }
+ defer { print("Second") }
+ defer { print("Third") }
+}
+f()
+// 打印 “Third”
+// 打印 “Second”
+// 打印 “First”
+```
+
+`defer` 语句中的语句无法将控制权转移到 `defer` 语句外部。
> defer 语句语法
-> *延迟语句* → **defer** *[代码块](TODO)*
-
+
+> *延迟语句* → **defer** [*代码块*](05_Declarations.md#code-block)
-### Do 语句
+## Do 语句
-`do` 语句用于引入一个新的作用域,该作用域中可以含有一个或多个`catch`子句,catch子句中定义了一些匹配错误情况的模式。`do` 语句作用域内定义的常量和变量,只能在do语句作用域内访问。
+`do` 语句用于引入一个新的作用域,该作用域中可以含有一个或多个 `catch` 子句,`catch` 子句中定义了一些匹配错误条件的模式。`do` 语句作用域内定义的常量和变量只能在 `do` 语句作用域内使用。
-swift 中的 do 语句与C 中限定代码块界限的大括号 ({})很相似,并且在程序运行的时候并不会造成系统开销。
+Swift 中的 `do` 语句与 C 中限定代码块界限的大括号(`{}`)很相似,也并不会降低程序运行时的性能。
-> do {
-> try `expression`
-> `statements`
-> } catch `pattern 1` {
- `statements`
-> } catch `pattern 2` where condition {
- `statements`
-> }
+`do` 语句的形式如下:
-如同`switch`语句,编译器会判断`catch`子句是否被遗漏。如果catch没有被遗漏,则认为错误被处理。否则,错误会自动传播出包含作用域,被一个封闭的`catch`语句或抛出函数处理掉,包含函数必须以`throws`关键字声明。
+```swift
+do {
+ try 表达式
+ 语句
+} catch 模式1 {
+ 语句
+} catch 模式2 where 条件 {
+ 语句
+}
+```
-为了确保错误已经被处理,使用一个匹配所有错误的`catch`子句,如通配符模式(_)。如果一个`catch`子句不指定一种模式,`catch`子句会匹配和约束任何局部变量命名的`error`。有关在`catch`子句中使用模式的更多信息,详见[模式](TODO)。
+如同 `switch` 语句,编译器会判断 `catch` 子句是否有遗漏。如果 `catch` 子句没有遗漏,则认为错误已被处理。否则,错误会自动传递到外围作用域,被某个 `catch` 子句处理掉或者被用 `throws` 关键字声明的抛出函数继续向外抛出。
-关于在一些`catch`子句中如何使用` do`语句的例子,详情参见[错误处理](TODO)一章的[抛出错误](TODO)。
+为了确保错误已经被处理,可以让 `catch` 子句使用匹配所有错误的模式,如通配符模式(`_`)。如果一个 `catch` 子句不指定一种具体模式,`catch` 子句会匹配任何错误,并绑定到名为 `error` 的局部常量。有关在 `catch` 子句中使用模式的更多信息,请参阅 [模式](07_Patterns.md)。
-> do 语句语法 → **do** *[*代码块*](../chapter3/05_Declarations.html#code_block) [catch](TODO)*
-> catch → *[catch子句](TODO) [catch子句](TODO)*
-> catch → **catch** *[*模式*](../chapter3/07_Patterns.html#pattern)** *可选的* [*where*]() *可选的* [*代码块*](../chapter3/05_Declarations.html#code_block)
+关于如何在 `do` 语句中使用一系列 `catch` 子句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md#handling_errors)。
+
+> do 语句语法
+
+> *do 语句* → **do** [*代码块*](05_Declarations.md#code-block) [*多条 catch子句*](#catch-clauses)可选
+
+> *多条 catch 子句* → [*catch子句*](#catch-clause) [*多条 catch子句*](#catch-clauses)可选
+
+> *catch 子句* → **catch** [*模式*](07_Patterns.md#pattern)可选 [*where子句*](#where-clause)可选 [*代码块*](05_Declarations.md#code-block)
-### 编译控制语句
+## 编译器控制语句
-编译控制语句允许程序改变编译器的行为。Swift 有两种编译控制语句:构建配置语句和源代码控制语句。
+编译器控制语句允许程序改变编译器的行为。Swift 有两种编译器控制语句:编译配置语句和线路控制语句。
-> 编译控制语句语法
-> *编译控制语句* → [*构建配置语句*](../chapter3/04_Expressions.html#build_config_statements)
-> *编译控制语句* → [*源代码控制语句*](../chapter3/04_Expressions.html#line_control_statements)
+> 编译器控制语句语法
+
+> *编译器控制语句* → [*编译配置语句*](#build-config-statement)
+> *编译器控制语句* → [*线路控制语句*](#line-control-statement)
-#### 构建配置语句
+### 编译配置语句
-构建配置语句可以根据一个或多个配置项来有条件的编译代码。
+编译配置语句可以根据一个或多个配置来有条件地编译代码。
-每一个构建配置语句都以 `#if` 开始, `#endif` 结束。如下是一个简单的构建配置语句:
+每一个编译配置语句都以 `#if` 开始,`#endif` 结束。如下是一个简单的编译配置语句:
-```
-#if build configuration
-statements
+```swift
+#if 编译配置项
+ 语句
#endif
```
-和 `if` 语句的条件不同,构建配置的条件是在编译时进行判断的。它的结果是:只有构建配置在编译时判断为 `true` 的情况下语句才会被编译和执行。
+和 `if` 语句的条件不同,编译配置的条件是在编译时进行判断的。只有编译配置在编译时判断为 `true` 的情况下,相应的语句才会被编译和执行。
-*构建配置* 可以是 `true` 和 `false` 的常量,也可以是使用 `-D` 命令行标志的标识符,或者是下列表格中的任意一个平台测试方法。
+编译配置可以是 `true` 和 `false` 的字面量,也可以是使用 `-D` 命令行标志的标识符,或者是下列表格中的任意一个平台检测函数。
- | 方法 | 可用参数 |
- | --- | - |
- | os() | OSX, iOS, watchOS, tvOS |
- | arch() | i386, x86_64, arm, arm64 |
-
+| 函数 | 可用参数 |
+| --- | --- |
+| `os()` | `OSX`, `iOS`, `watchOS`, `tvOS`, `Linux` |
+| `arch()` | `i386`, `x86_64`, `arm`, `arm64` |
+| `swift()` | `>=` 后跟版本号 |
-> 注意
-> `arch(arm)` 构建配置在 ARM 64位设备上不会返回 `true`。如果代码的构建目标是 32 位的 iOS 模拟器,`arch(i386)` 构建配置返回 `true`。
+`swift()`(语言版本检测函数)的版本号参数主要由主版本号和次版本号组成并且使用点号(`.`)分隔开,`>=` 和版本号之间不能有空格。
-你可以使用逻辑操作符 `&&`、`||` 和 `!` 来连接构建配置,还可以使用圆括号来进行分组。
+> 注意
+> `arch(arm)` 平台检测函数在 ARM 64 位设备上不会返回 `true`。如果代码在 32 位的 iOS 模拟器上编译,`arch(i386)` 平台检测函数会返回 `true`。
-就像 `if` 语句一样,你可以使用 `#elseif` 分句来添加任意多个条件分支来测试不同的构建配置。你也可以使用 `#else` 分句来添加最终的条件分支。包含多个分支的构建配置语句例子如下:
+你可以使用逻辑操作符 `&&`、`||` 和 `!` 来组合多个编译配置,还可以使用圆括号来进行分组。
-```
-#if build configuration 1
-statements to compile if build configuration 1 is true
-#elseif build configuration 2
-statements to compile if build configuration 2 is true
+就像 `if` 语句一样,你可以使用 `#elseif` 子句来添加任意多个条件分支来测试不同的编译配置。你也可以使用 `#else` 子句来添加最终的条件分支。包含多个分支的编译配置语句例子如下:
+
+```swift
+#if 编译配置1
+ 如果编译配置1成立则执行这部分代码
+#elseif 编译配置2
+ 如果编译配置2成立则执行这部分代码
#else
-statements to compile if both build configurations are false
+ 如果编译配置均不成立则执行这部分代码
#endif
```
-> 注意
-> 即使没有被编译,构建配置语句中的每一个分句仍然会被解析。
+> 注意
+> 即使没有被编译,编译配置中的语句仍然会被解析。然而,唯一的例外是编译配置语句中包含语言版本检测函数:仅当 `Swift` 编译器版本和语言版本检测函数中指定的版本号匹配时,语句才会被解析。这种设定能确保旧的编译器不会尝试去解析新 Swift 版本的语法。
----
-> 构建配置语句语法
-> 单个构建配置语句 → #if 多个构建配置语句(可选) 多个构建配置 `elseif` 分句(可选) 单个构建配置 `else` 分句(可选)#endif
-> 多个构建配置 `elseif` 分句 → 单个构建配置 `elseif` 分句 多个构建配置 `elseif` 分句(可选)
-> 单个构建配置 `elseif` 分句 → #elseif 多个构建配置语句(可选)
-> 单个构建配置 `else` 分句 → #else 语句(可选)
-> 构建配置 → 平台测试方法
-> 构建配置 → 标识符
-> 构建配置 → boolean 常量
-> 构建配置 → (构建配置)
-> 构建配置 → ! 构建配置
-> 构建配置 → 构建配置 && 构建配置
-> 构建配置 → 构建配置 || 构建配置
-> 平台测试方法 → os(操作系统)
-> 平台测试方法 → arch(架构)
-> 操作系统 → OSX iOS watchOS tvOS
-> 架构 → i386 x86_64 arm arm64
+
+> 编译配置语句语法
+
+
+> *单个编译配置语句* → **#if** [*编译配置*](#build-configuration) [*语句*](#statements)可选 [*多个编译配置elseif子句*](#build-configuration-elseif-clauses)可选 **-** [*单个编译配置else子句*](#build-configuration-else-clause)可选 **#endif**
+
+> *多个编译配置 elseif 子句* → [*单个编译配置elseif子句*](#build-configuration-elseif-clause) [*多个编译配置elseif子句*](build-configuration-elseif-clauses)可选
+
+> *单个编译配置 elseif 子句* → **#elseif** [*编译配置*](#build-configuration) [*语句*](#statements)可选
+
+> *单个编译配置 else 子句* → **#else** [*语句*](#statements)可选
+
+
+> *编译配置* → [*平台检测函数*](#platform-testing-function)
+> *编译配置* → [*语言版本检测函数*](#language-version-testing-function)
+> *编译配置* → [*标识符*](02_Lexical_Structure.md#identifier)
+> *编译配置* → [*布尔值字面量*](02_Lexical_Structure.md#boolean-literal)
+> *编译配置* → **(** [*编译配置*](#build-configuration) **)**
+> *编译配置* → **!** [*编译配置*](#build-configuration)
+> *编译配置* → [*编译配置*](#build-configuration) **&&** [*编译配置*](#build-configuration)
+> *编译配置* → [*编译配置*](#build-configuration) **||** [*编译配置*](#build-configuration)
+
+
+> *平台检测函数* → **os** **(** [*操作系统*](#operating-system) **)**
+> *平台检测函数* → **arch** **(** [*架构*](#architecture) **)**
+
+> *语言版本检测函数* → **swift** **(** **>=** [*swift版本*](#swift-version) **)**
+
+> *操作系统* → **OSX** | **iOS** | **watchOS** | **tvOS**
+
+> *架构* → **i386** | **x86_64** | **arm** | **arm64**
+
+> *swift 版本* → [*十进制数字*](02_Lexical_Structure.md#decimal-digit) **.** [*十进制数字*](02_Lexical_Structure.md#decimal-digit)
-#### 源代码控制语句
+### 行控制语句
-源代码控制语句用来给被编译源代码指定一个与原始行号和文件名不同的行号和文件名。使用源代码控制语句可以改变 Swift 使用源代码的位置,以便进行分析和测试。
+行控制语句可以为被编译的源代码指定行号和文件名,从而改变源代码的定位信息,以便进行分析和调试。
-源代码的控制语句的例子如下:
+行控制语句形式如下:
-```
-#line line number filename
+> \#sourceLocation(file: `文件名` , line:`行号`)
+
+> \#sourceLocation()
+
+第一种的行控制语句会改变该语句之后的代码中的字面量表达式 `#line` 和 `#file` 所表示的值。`行号` 是一个大于 0 的整形字面量,会改变 `#line` 表达式的值。`文件名` 是一个字符串字面量,会改变 `#file` 表达式的值。
+
+第二种的行控制语句, `#sourceLocation()`,会将源代码的定位信息重置回默认的行号和文件名。
+
+
+> 行控制语句语法
+
+> *行控制语句* → **#sourceLocation(file:[*文件名*](#file-name),line:[*行号*](#line-number))**
+> *行控制语句* → **#sourceLocation()**
+
+> *行号* → 大于 0 的十进制整数
+
+> *文件名* → [*静态字符串字面量*](02_Lexical_Structure.md#static-string-literal)
+
+
+### 可用性条件
+
+可用性条件可作为 `if`,`while`,`guard` 语句的条件,可以在运行时基于特定的平台参数来查询 API 的可用性。
+
+可用性条件的形式如下:
+
+```swift
+if #available(平台名称 版本, ..., *) {
+ 如果 API 可用,则执行这部分语句
+} else {
+ 如果 API 不可用,则执行这部分语句
+}
```
-源代码控制语句改变了常量表达式 `__LINE__` 和 `__FILE__` 的值,以一行源代码开头,然后跟着源代码控制语句。`line number` 改变了 `__LINE__` 的值,它是一个大于 0 的常量。`filename` 改变了 `__FILE__` 的值,它是一个字符串常量。
+使用可用性条件来执行一个代码块时,取决于使用的 API 在运行时是否可用,编译器会根据可用性条件提供的信息来决定是否执行相应的代码块。
-你可以通过写一句不指定 `line number` 和 `filename` 的源代码控制语句来吧源代码的位置回退到初始的行号和文件。
+可用性条件使用一系列逗号分隔的平台名称和版本。使用 `iOS`,`OSX`,以及 `watchOS` 等作为平台名称,并写上相应的版本号。`*` 参数是必须写的,用于处理未来的潜在平台。可用性条件确保了运行时的平台不低于条件中指定的平台版本时才执行代码块。
+
+与布尔类型的条件不同,不能用逻辑运算符 `&&` 和 `||` 组合可用性条件。
-源代码控制语句必须出现在源代码的那一行,而且不能是源代码文件的最后一行。
+> 可用性条件语法
-> 源代码控制语句
+
+> *可用性条件* → **#available** **(** [*可用性参数列表*](#availability-arguments) **)**
+
+> *可用性参数列表* → [*可用性参数*](#availability-argument) | [*可用性参数*](#availability-argument) **,** [*可用性参数列表*](#availability-arguments)
+
+> *可用性参数* → [平台名称](#platform-name) [平台版本](#platform-version)
+> *可用性条件* → __*__
-> 源代码控制语句 → #line
-> 源代码控制语句 → #line line-number file-name
-> line-number → 大于 0 的十进制数
-> file-name → 字符串常量
+
+> *平台名称* → **iOS** | **iOSApplicationExtension**
+> *平台名称* → **OSX** | **OSXApplicationExtension**
+> *平台名称* → **watchOS**
+
+> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits)
+> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
+> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-