Translations for Swift 4.1 (#777)
* Translations for Chapter 3 part 01 for Swift 4.0/4.1 * update chapter 3 part 02 for swift 4.1 * update chapter 3 part 03 for Swift 4.1 * update chapter 1 part 01 for Swift 4.1 * update chapter 1 part 02 for Swift 4.1 * update chapter 1 part 03 for Swift 4.1 * update chapter 2 part 01 for Swift 4.1 * update chapter 2 part 02 for Swift 4.1 * update chapter 2 part 3 for Swift 4.1 * update "summary" and corrected file names * update chapter 2 part 4 for Swift 4.1 * update chapter 2 part 5 for Swift 4.1 * update chapter 2 part 6 for Swift 4.1 * update chapter 2 parts 06-11 and other parts' errors * update chapter 2 parts 12-14 * update chapter 2 parts 14-19 * update all chapter 2 * update whole chapter 1 * update some parts of chapter 3
This commit is contained in:
@ -8,13 +8,16 @@
|
||||
> 2.0
|
||||
> 翻译+校对:[KYawn](https://github.com/KYawn)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页内容包括:
|
||||
|
||||
- [如何阅读语法](#how_to_read_the_grammar)
|
||||
|
||||
本书的这一节描述了 Swift 编程语言的形式语法。这里描述的语法是为了帮助您更详细地了解该语言,而不是让您直接实现一个解析器或编译器。
|
||||
本书的这一节描述了 Swift 编程语言的形式语法。这里描述的语法是为了帮助您了解该语言的更多细节,而不是让您直接实现一个解析器或编译器。
|
||||
|
||||
Swift 语言相对较小,这是由于 Swift 代码中的几乎所有常见类型、函数以及运算符都已经在 Swift 标准库中定义了。虽然这些类型、函数和运算符并不是 Swift 语言自身的一部分,但是它们被广泛应用于本书的讨论和代码范例中。
|
||||
Swift 语言相对较小,这是由于 Swift 代码中在各种地方出现的常见的类型、函数以及运算符都已经在 Swift 标准库中定义了。虽然这些类型、函数和运算符并不是 Swift 语言自身的一部分,但是它们被广泛应用于本书的讨论和代码范例中。
|
||||
|
||||
<a name="how_to_read_the_grammar"></a>
|
||||
## 如何阅读语法
|
||||
@ -23,18 +26,20 @@ Swift 语言相对较小,这是由于 Swift 代码中的几乎所有常见类
|
||||
|
||||
- 箭头(`→`)用来标记语法产式,可以理解为“可由……构成”。
|
||||
- 斜体文字用来表示句法类型,并出现在一个语法产式规则两侧。
|
||||
- 关键字和标点符号由固定宽度的粗体文本表示,只出现在一个语法产式规则的右侧。
|
||||
- 标记语言和标点符号由固定宽度的粗体文本表示,只出现在一个语法产式规则的右侧。
|
||||
- 可供选择的语法产式由竖线(`|`)分隔。当可选用的语法产式太多时,为了阅读方便,它们将被拆分为多行语法产式规则。
|
||||
- 少数情况下,语法产式规则的右侧会有用于描述的常规字体文字。
|
||||
- 可选的句法类型和字面值用尾标 `opt` 来标记。
|
||||
- 少数情况下,标准字体文本被用来描述一个语法产生规则的右手侧内容。
|
||||
- 可选的句法类型和文本标记用尾标 `opt` 来标记。
|
||||
|
||||
举个例子,getter-setter 的语法块的定义如下:
|
||||
举个例子,getter-setter 方法块的语法定义如下:
|
||||
|
||||
> getter-setter 方法块语法
|
||||
> getter-setter 方法块语法
|
||||
>
|
||||
> *getter-setter 方法块* → { [*getter 子句*](05_Declarations.html#getter-clause) [*setter 子句*](05_Declarations.html#setter-clause)<sub>可选</sub> } | { [*setter 子句*](05_Declarations.html#setter-clause) [*getter 子句*](05_Declarations.html#getter-clause) }
|
||||
|
||||
这个定义表明,一个 getter-setter 方法块可以由一个 getter 子句后跟一个可选的 setter 子句构成,然后用大括号括起来,或者由一个 setter 子句后跟一个 getter 子句构成,然后用大括号括起来。下面的两个语法产式等价于上述的语法产式,并明确指出了如何取舍:
|
||||
这个定义表明,一个 getter-setter 方法块可以由一个 getter 分句后跟一个可选的 setter 分句构成,然后用大括号括起来,或者由一个 setter 分句后跟一个 getter 分句构成,然后用大括号括起来。上述的语法产式等价于下面的两个语法产式, :
|
||||
|
||||
> getter-setter 方法块语法
|
||||
> getter-setter 方法块语法
|
||||
>
|
||||
> getter-setter 方法块 → { [*getter 子句*](05_Declarations.html#getter-clause) [*setter 子句*](05_Declarations.html#setter-clause)<sub>可选</sub> }
|
||||
> getter-setter 方法块 → { [*setter 子句*](05_Declarations.html#setter-clause) [*getter 子句*](05_Declarations.html#getter-clause) }
|
||||
|
||||
@ -12,7 +12,10 @@
|
||||
> 翻译:[mmoaay](https://github.com/mmoaay)
|
||||
|
||||
> 2.2
|
||||
> 翻译+校对:[星夜暮晨](https://github.com/semperidem),2016-04-06
|
||||
> 翻译+校对:[星夜暮晨](https://github.com/semperidem)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
|
||||
@ -25,7 +28,7 @@
|
||||
- [字符串字面量](#string_literals)
|
||||
- [运算符](#operators)
|
||||
|
||||
Swift 的*“词法结构 (lexical structure)”* 描述了能构成该语言中合法符号 (token) 的字符序列。这些合法符号组成了语言中最底层的构建基块,并在之后的章节中用于描述语言的其他部分。一个合法符号由一个标识符 (identifier)、关键字 (keyword)、标点符号 (punctuation)、字面量 (literal) 或运算符 (operator) 组成。
|
||||
Swift 的*“词法结构 (lexical structure)”* 描述了能构成该语言中有效符号 (token) 的字符序列。这些合法符号组成了语言中最底层的构建基块,并在之后的章节中用于描述语言的其他部分。一个合法符号由一个标识符 (identifier)、关键字 (keyword)、标点符号 (punctuation)、字面量 (literal) 或运算符 (operator) 组成。
|
||||
|
||||
通常情况下,通过考虑输入文本当中可能的最长子串,并且在随后将介绍的语法约束之下,根据随后将介绍的语法约束生成的,根据 Swift 源文件当中的字符来生成相应的“符号”。这种方法称为*“最长匹配 (longest match)”*,或者*“最大适合(maximal munch)”*。
|
||||
|
||||
@ -36,7 +39,31 @@ Swift 的*“词法结构 (lexical structure)”* 描述了能构成该语言中
|
||||
|
||||
注释被编译器当作空白处理。单行注释由 `//` 开始直至遇到换行符(U+000A)或者回车符(U+000D)。多行注释由 `/*` 开始,以 `*/` 结束。注释允许嵌套,但注释标记必须匹配。
|
||||
|
||||
正如 [*Markup Formatting Reference*](https://developer.apple.com/library/prerelease/ios/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html#//apple_ref/doc/uid/TP40016497) 所述,注释可以包含附加的格式和标记。
|
||||
> 空白语法
|
||||
|
||||
<a id="whitespace"></a>
|
||||
> *空白* → [*空白项*](#whitespace-item) [*空白*](#whitespace)<sub>可选</sub>
|
||||
> *空白项* → [*断行符*](#line-break)
|
||||
> *空白项* → [*注释*](#comment)
|
||||
> *空白项* → [*多行注释*](#multiline-comment)
|
||||
> *空白项* → U+0000,U+0009,U+000B,U+000C 或者 U+0020
|
||||
|
||||
<a id="line-break"></a>
|
||||
> *断行符* → U+000A
|
||||
> *断行符* → U+000D
|
||||
> *断行符* → U+000D 接着是 U+000A
|
||||
|
||||
<a id="comment"></a>
|
||||
> *注释* → // [*注释内容 断行*](#comment-text line-break)
|
||||
> *多行注释* → `/*` [*多行注释内容*](#multiline-commnet-text) `*/`
|
||||
> *注释内容* → [*注释内容项*](#comment-text-item) [*注释内容*](#comment-text)<sub>可选</sub>
|
||||
> *注释内容项* → 任何Unicode标量值, 除了 U+000A 或者 U+000D
|
||||
> *多行注释内容* → [*多行注释内容项*](#multiline-comment-text-item) [*多行注释内容*](#multiline-comment-text)<sub>可选</sub>
|
||||
> *多行注释内容项* → [*多行注释*](#multiline-comment).
|
||||
> *多行注释内容项* → [*注释内容项*](#comment-text-item)
|
||||
> *多行注释内容项* → 任何Unicode标量值, 除了 `/*` 或者 `*/`
|
||||
|
||||
注释可以包含额外的格式和标记,正如 [*Markup Formatting Reference*](https://developer.apple.com/library/prerelease/ios/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html#//apple_ref/doc/uid/TP40016497) 所述。
|
||||
|
||||
<a id="identifiers"></a>
|
||||
## 标识符
|
||||
@ -117,7 +144,8 @@ true // 布尔值字面量
|
||||
|
||||
当为一个字面量值指定了类型标注的时候,这个标注的类型必须能通过这个字面量值实例化。也就是说,这个类型必须符合这些 Swift 标准库协议中的一个:整数字面量的 `IntegerLiteralConvertible` 协议、浮点数字面量的 `FloatingPointLiteralConvertible` 协议、字符串字面量的 `StringLiteralConvertible` 协议以及布尔值字面量的 `BooleanLiteralConvertible` 协议。比如,`Int8` 符合 `IntegerLiteralConvertible` 协议,因此它能在 `let x: Int8 = 42` 这个声明中作为整数字面量 `42` 的类型标注。
|
||||
|
||||
> 字面量语法
|
||||
> 字面量语法
|
||||
>
|
||||
> *字面量* → [*数值字面量*](#numeric-literal) | [*字符串字面量*](#string-literal) | [*布尔值字面量*](#boolean-literal) | [*nil 字面量*](#nil-literal)
|
||||
|
||||
<a id="numeric-literal"></a>
|
||||
@ -141,7 +169,7 @@ true // 布尔值字面量
|
||||
除非特别指定,整数字面量的默认推导类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数](../chapter2/01_The_Basics.html#integers)。
|
||||
|
||||
> 整数字面量语法
|
||||
|
||||
>
|
||||
<a id="integer-literal"></a>
|
||||
> *整数字面量* → [*二进制字面量*](#binary-literal)
|
||||
> *整数字面量* → [*八进制字面量*](#octal-literal)
|
||||
@ -204,7 +232,7 @@ true // 布尔值字面量
|
||||
除非特别指定,浮点数字面量的默认推导类型为 Swift 标准库类型中的 `Double`,表示 64 位浮点数。Swift 标准库也定义了 `Float` 类型,表示 32 位浮点数。
|
||||
|
||||
> 浮点数字面量语法
|
||||
|
||||
>
|
||||
<a id="floating-point-literal"></a>
|
||||
> *浮点数字面量* → [*十进制字面量*](#decimal-literal) [*十进制分数*](#decimal-fraction)<sub>可选</sub> [*十进制指数*](#decimal-exponent)<sub>可选</sub>
|
||||
> *浮点数字面量* → [*十六进制字面量*](#hexadecimal-literal) [*十六进制分数*](#hexadecimal-fraction)<sub>可选</sub> [*十六进制指数*](#hexadecimal-exponent)
|
||||
@ -229,12 +257,27 @@ true // 布尔值字面量
|
||||
<a id="string_literals"></a>
|
||||
### 字符串字面量
|
||||
|
||||
字符串字面量由被包在双引号中的一串字符组成,形式如下:
|
||||
字符串字面量是被引号包括的一串字符组成。 单行字符串字面量被包在双引号中的一串字符组成,形式如下:
|
||||
|
||||
> "`字符`"
|
||||
|
||||
字符串字面量中不能包含未转义的双引号(`"`)、未转义的反斜线(`\`)、回车符、换行符。
|
||||
|
||||
多行字符串字面量被包在三个双引号中的一串字符组成,形式如下:
|
||||
> """
|
||||
> `字符`
|
||||
> """
|
||||
|
||||
与单行字符串字面量不同的是,多行字符串字面量可以包含不转义的双引号( " ),回车以及换行。它不能包含三个非转义的连续双引号。
|
||||
|
||||
""" 之后的回车或者换行开始多行字符串字面量,不是字符串的一部分。 """ 之前回车或者换行结束字面量,也不是字符串的一部分。要让多行字符串字面量的开始或结束带有换行,就在第一行或者最后一行写一个空行。
|
||||
|
||||
多行字符串字面量可以使用任何空格或制表符组合进行缩进;这些缩进不会包含在字符串中。 """ 的结束符号决定了缩进:字面量中的任何一个非空行必须起始于多行字符串字面量结束符号的前面;空格和制表符不会被转换。你可以包在缩进后含额外的空格和制表符;这些空格和制表符会在字符串中出现。
|
||||
|
||||
多行字符串字面量中的一行结束使用规范化的换行符号。尽管你的源代码混用了回车和换行符,字符串中所有的行结束都必须一样.
|
||||
|
||||
在多行字符串字面量里, 在行末用反斜线(`\`)可以省略字符串行间中断。 反斜线之间的空白和行间中断也可以省略。 你可以在你的代码里用这种语法硬包裹多行字符串字面量,不需要改变产生的字符串的值。
|
||||
|
||||
可以在字符串字面量中使用的转义特殊符号如下:
|
||||
|
||||
* 空字符 `\0`
|
||||
@ -246,7 +289,7 @@ true // 布尔值字面量
|
||||
* 单引号 `\'`
|
||||
* Unicode 标量 `\u{`n`}`,n 为一到八位的十六进制数字
|
||||
|
||||
字符串字面量允许在反斜杠 (`\`) 后的括号 `()` 中插入表达式的值。插入表达式可以包含字符串字面量,但不能包含未转义的双引号 (`"`)、未转义的反斜线 (`\`)、回车符以及换行符。
|
||||
字符串字面量允许在反斜杠 (`\`) 后的括号 `()` 中插入表达式的值。插入表达式可以包含字符串字面量,但不能包含未转义的反斜线 (`\`)、回车符以及换行符。
|
||||
|
||||
例如,以下所有字符串字面量的值都是相同的:
|
||||
|
||||
@ -258,7 +301,7 @@ true // 布尔值字面量
|
||||
let x = 3; "1 2 \(x)"
|
||||
```
|
||||
|
||||
字符串字面量的默认推导类型为 `String`。更多有关 `String` 类型的信息请参考 [字符串和字符](../chapter2/03_Strings_and_Characters.html) 以及 [*String Structure Reference*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_String_Structure/index.html#//apple_ref/doc/uid/TP40015181)。
|
||||
字符串字面量的默认推导类型为 `String`。更多有关 `String` 类型的信息请参考 [字符串和字符](../chapter2/03_Strings_and_Characters.html) 以及 [*字符串结构参考*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_String_Structure/index.html#//apple_ref/doc/uid/TP40015181)。
|
||||
|
||||
用 `+` 操作符连接的字符型字面量是在编译时进行连接的。比如下面的 `textA` 和 `textB` 是完全一样的,`textA` 没有任何运行时的连接操作。
|
||||
|
||||
@ -268,7 +311,7 @@ let textB = "Hello world"
|
||||
```
|
||||
|
||||
> 字符串字面量语法
|
||||
|
||||
>
|
||||
<a id="string-literal"></a>
|
||||
> *字符串字面量* → [*静态字符串字面量*](#static-string-literal) | [*插值字符串字面量*](#interpolated-string-literal)
|
||||
|
||||
@ -304,7 +347,8 @@ Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基
|
||||
|
||||
虽然您可以用问号 `?` 来自定义运算符,但是这个运算符不能只包含单独的一个问号。此外,虽然运算符可以包含一个惊叹号 `!`,但是前缀运算符不能够以问号或者惊叹号开头。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 以下这些标记 `=`、`->`、`//`、`/*`、`*/`、`.`、`<`(前缀运算符)、`&`、`?`、`?`(中缀运算符)、`>`(后缀运算符)、`!` 、`?` 是被系统保留的。这些符号不能被重载,也不能用于自定义运算符。
|
||||
|
||||
运算符两侧的空白被用来区分该运算符是否为前缀运算符、后缀运算符或二元运算符。规则总结如下:
|
||||
@ -323,7 +367,7 @@ Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基
|
||||
要学习如何自定义运算符,请参考 [自定义运算符](../chapter2/25_Advanced_Operators.html#custom_operators) 和 [运算符声明](05_Declarations.html#operator_declaration)。要学习如何重载运算符,请参考 [运算符函数](../chapter2/25_Advanced_Operators.html#operator_functions)。
|
||||
|
||||
> 运算符语法
|
||||
|
||||
>
|
||||
<a id="operator"></a>
|
||||
> *运算符* → [*头部运算符*](#operator-head) [*运算符字符组*](#operator-characters)<sub>可选</sub>
|
||||
> *运算符* → [*头部点运算符*](#dot-operator-head) [*点运算符字符组*](#dot-operator-characters)<sub>可选</sub>
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
|
||||
> 2.1
|
||||
> 翻译:[mmoaay](https://github.com/mmoaay)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
|
||||
@ -30,13 +33,27 @@ Swift 语言存在两种类型:命名型类型和复合型类型。命名型
|
||||
|
||||
那些通常被其它语言认为是基本或原始的数据型类型,比如表示数字、字符和字符串的类型,实际上就是命名型类型,这些类型在 Swift 标准库中是使用结构体来定义和实现的。因为它们是命名型类型,因此你可以按照 [扩展](../chapter2/21_Extensions.html) 和 [扩展声明](05_Declarations.html#extension_declaration) 中讨论的那样,声明一个扩展来增加它们的行为以满足你程序的需求。
|
||||
|
||||
复合型类型是没有名字的类型,它由 Swift 本身定义。Swift 存在两种复合型类型:函数类型和元组类型。一个复合型类型可以包含命名型类型和其它复合型类型。例如,元组类型 `(Int, (Int, Int))` 包含两个元素:第一个是命名型类型 `Int`,第二个是另一个复合型类型 `(Int, Int)`。
|
||||
复合型类型是没有名字的类型,它由 Swift 本身定义。Swift 存在两种复合型类型:函数类型和元组类型。一个复合型类型可以包含命名型类型和其它复合型类型。例如,元组类型 `(Int, (Int, Int))` 包含两个元素:第一个是命名型类型 `Int`,第二个是另一个复合型类型 `(Int, Int)`。
|
||||
|
||||
你可以在命名型类型和复合型类型使用小括号。但是在类型旁加小括号没有任何作用。举个例子,`(Int)`等同于`Int`。
|
||||
|
||||
本节讨论 Swift 语言本身定义的类型,并描述 Swift 中的类型推断行为。
|
||||
|
||||
> 类型语法
|
||||
> 类型语法
|
||||
>
|
||||
<a name="type"></a>
|
||||
> *类型* → [*数组类型*](#array-type) | [*字典类型*](#dictionary-type) | [*函数类型*](#function-type) | [*类型标识*](#type-identifier) | [*元组类型*](#tuple-type) | [*可选类型*](#optional-type) | [*隐式解析可选类型*](#implicitly-unwrapped-optional-type) | [*协议合成类型*](#protocol-composition-type) | [*元型类型*](#metatype-type) | **任意类型** | **自身类型**
|
||||
> *类型* → [*数组类型*](#array-type)
|
||||
> *类型* → [*字典类型*](#dictionary-type)
|
||||
> *类型* → [*函数类型*](#function-type)
|
||||
> *类型* → [*类型标识*](#type-identifier)
|
||||
> *类型* → [*元组类型*](#tuple-type)
|
||||
> *类型* → [*可选类型*](#optional-type)
|
||||
> *类型* → [*隐式解析可选类型*](#implicitly-unwrapped-optional-type)
|
||||
> *类型* → [*协议合成类型*](#protocol-composition-type)
|
||||
> *类型* → [*元型类型*](#metatype-type)
|
||||
> *类型* → **任意类型**
|
||||
> *类型* → **自身类型**
|
||||
> *类型* → [*(类型)*](#type)
|
||||
|
||||
<a name="type_annotation"></a>
|
||||
## 类型注解
|
||||
@ -51,7 +68,8 @@ func someFunction(a: Int) { /* ... */ }
|
||||
|
||||
类型注解可以在类型之前包含一个类型特性的可选列表。
|
||||
|
||||
> 类型注解语法
|
||||
> 类型注解语法
|
||||
>
|
||||
<a name="type-annotation"></a>
|
||||
> *类型注解* → **:** [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> **输入输出参数**<sub>可选</sub> [*类型*](#type)
|
||||
|
||||
@ -75,7 +93,8 @@ let origin: Point = (0, 0)
|
||||
var someValue: ExampleModule.MyType
|
||||
```
|
||||
|
||||
> 类型标识符语法
|
||||
> 类型标识符语法
|
||||
>
|
||||
<a name="type-identifier"></a>
|
||||
> *类型标识符* → [*类型名称*](#type-name) [*泛型参数子句*](08_Generic_Parameters_and_Arguments.html#generic_argument_clause)<sub>可选</sub> | [*类型名称*](#type-name) [*泛型参数子句*](08_Generic_Parameters_and_Arguments.html#generic_argument_clause)<sub>可选</sub> **.** [*类型标识符*](#type-identifier)
|
||||
<a name="type-name"></a>
|
||||
@ -97,16 +116,17 @@ someTuple = (9, 99) // 正确:命名类型被自动推断
|
||||
someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
||||
```
|
||||
|
||||
`Void` 是空元组类型 `()` 的别名。如果括号内只有一个元素,那么该类型就是括号内元素的类型。比如,`(Int)` 的类型是 `Int` 而不是 `(Int)`。所以,只有当元组类型包含的元素个数在两个及以上时才可以命名元组元素。
|
||||
所有的元组类型都包含两个及以上元素, 除了`Void`。 `Void` 是空元组类型 `()` 的别名。
|
||||
|
||||
> 元组类型语法
|
||||
> 元组类型语法
|
||||
>
|
||||
<a name="tuple-type"></a>
|
||||
> *元组类型* → **(** [*元组类型元素列表*](#tuple-type-element-list) <sub>可选</sub> **)**
|
||||
<a name="tuple-type-element-list"></a>
|
||||
> *元组类型元素列表* → [*元组类型元素*](#tuple-type-element) | [*元组类型元素*](#tuple-type-element) **,** [*元组类型元素列表*](#tuple-type-element-list)
|
||||
<a name="tuple-type-element"></a>
|
||||
> *元组类型元素* → [*元素名*](#element-name) [*类型注解*](#type-annotation) | [*类型*](#type)
|
||||
<a name="element-name"></a>
|
||||
<a name="element-name"></a>
|
||||
> *元素名* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
|
||||
<a name="function_type"></a>
|
||||
@ -118,13 +138,15 @@ someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
||||
|
||||
参数类型是由逗号间隔的类型列表。由于参数类型和返回值类型可以是元组类型,所以函数类型支持多参数与多返回值的函数与方法。
|
||||
|
||||
你可以对函数参数使用 `autoclosure` 特性。这会自动将参数表达式转化为闭包,表达式的结果即闭包返回值。这从语法结构上提供了一种便捷:延迟对表达式的求值,直到其值在函数体中被使用。以自动闭包做为参数的函数类型的例子详见 [自动闭包](../chapter2/07_Closures.html#autoclosures) 。
|
||||
你可以对函数参数`() - > T `(其中 T 是任何类型)使用 `autoclosure` 特性。这会自动将参数表达式转化为闭包,表达式的结果即闭包返回值。这从语法结构上提供了一种便捷:延迟对表达式的求值,直到其值在函数体中被调用。以自动闭包做为参数的函数类型的例子详见 [自动闭包](../chapter2/07_Closures.html#autoclosures) 。
|
||||
|
||||
函数类型可以拥有一个可变长参数作为参数类型中的最后一个参数。从语法角度上讲,可变长参数由一个基础类型名字紧随三个点(`...`)组成,如 `Int...`。可变长参数被认为是一个包含了基础类型元素的数组。即 `Int...` 就是 `[Int]`。关于使用可变长参数的例子,请参阅 [可变参数](../chapter2/06_Functions.html#variadic_parameters)。
|
||||
|
||||
为了指定一个 `in-out` 参数,可以在参数类型前加 `inout` 前缀。但是你不可以对可变长参数或返回值类型使用 `inout`。关于这种参数的详细讲解请参阅 [输入输出参数](../chapter2/06_Functions.html#in_out_parameters)。
|
||||
为了指定一个 `in-out` 参数,可以在参数类型前加 `inout` 前缀。但是你不可以对可变长参数或返回值类型使用 `inout`。关于这种参数的详细讲解请参阅 [输入输出参数](../chapter2/06_Functions.html#in_out_parameters)。
|
||||
|
||||
如果一个函数类型只有一个形式参数而且形式参数的类型是元组类型,那么元组类型在写函数类型的时候必须用圆括号括起来。比如说, `((Int, Int)) -> Void` 是接收一个元组 `(Int, Int)` 作为形式参数的函数的类型。与此相反,不加括号的`(Int, Int) -> Void` 是一个接收两个 `Int` 形式参数并且不返回任何值的函数的类型。相似地,因为`Void` 是空元组类型 `()` 的别名, 函数类型`(Void)-> Void`与一个空元组的变量的函数类型`(()) -> ()`是一样的。但这些类型和无变量的函数类型`() -> ()`是不一样的。
|
||||
|
||||
函数和方法中的参数名并不是函数类型的一部分。例如:
|
||||
函数和方法中的变量名并不是函数类型的一部分。例如:
|
||||
|
||||
```swift
|
||||
func someFunction(left: Int, right: Int) {}
|
||||
@ -141,22 +163,55 @@ func functionWithDifferentNumberOfArguments(left: Int, right: Int, top: Int) {}
|
||||
f = functionWithDifferentArgumentTypes // 错误
|
||||
f = functionWithDifferentNumberOfArguments // 错误
|
||||
```
|
||||
|
||||
由于变量标签不是函数类型的一部分,你可以在写函数类型的时候省略它们。
|
||||
|
||||
```
|
||||
var operation: (lhs: Int, rhs: Int) -> Int // 错误
|
||||
var operation: (_ lhs: Int, _ rhs: Int) -> Int // 正确
|
||||
var operation: (Int, Int) -> Int // 正确
|
||||
```
|
||||
|
||||
如果一个函数类型包涵多个箭头(->),那么函数类型将从右向左进行组合。例如,函数类型 `Int -> Int -> Int` 可以理解为 `Int -> (Int -> Int)`,也就是说,该函数类型的参数为 `Int` 类型,其返回类型是一个参数类型为 `Int`,返回类型为 `Int` 的函数类型。
|
||||
|
||||
函数类型若要抛出错误就必须使用 `throws` 关键字来标记,若要重抛错误则必须使用 `rethrows` 关键字来标记。`throws` 关键字是函数类型的一部分,非抛出函数是抛出函数函数的一个子类型。因此,在使用抛出函数的地方也可以使用不抛出函数。抛出和重抛函数的相关描述见章节 [抛出函数与方法](05_Declarations.html#throwing_functions_and_methods) 和 [重抛函数与方法](05_Declarations.html#rethrowing_functions_and_methods)。
|
||||
|
||||
<a name="Restrictions for Nonescaping Closures"></a>
|
||||
### 对非逃逸闭包的限制
|
||||
非逃逸闭包函数不能作为参数传递到另一个非逃逸闭包函数的参数。这样的限制可以让Swift在编译时就完成更多的内存访问冲突检查, 而不是在运行时。举个例子:
|
||||
|
||||
```
|
||||
let external: (Any) -> Void = { _ in () }
|
||||
func takesTwoFunctions(first: (Any) -> Void, second: (Any) -> Void) {
|
||||
first(first) // 错误
|
||||
second(second) // 错误
|
||||
|
||||
first(second) // 错误
|
||||
second(first) // 错误
|
||||
|
||||
first(external) // 正确
|
||||
external(first) // 正确
|
||||
}
|
||||
```
|
||||
在上面代码里,`takesTwoFunctions(first:second:)`的两个参数都是函数。 它们都没有标记为`@escaping`, 因此它们都是非逃逸的。
|
||||
|
||||
上述例子里的被标记为“错误”的四个函数调用会产生编译错误。因为第一个和第二个参数是非逃逸函数,它们不能够被当作变量被传递到另一个非闭包函数参数。与此相反, 标记“正确”的两个函数不回产生编译错误。这些函数调用不会违反限制, 因为`外部(external)`不是`takesTwoFunctions(first:second:)`里的一个参数。
|
||||
|
||||
如果你需要避免这个限制, 标记其中之一的参数为逃逸, 或者使用`withoutActuallyEscaping(_:do:)`函数临时地转换非逃逸函数的其中一个参数为逃逸函数。关于避免内存访问冲突,可以参阅[内存安全](../chapter2/24_Memory_Safety.html)。
|
||||
|
||||
|
||||
> 函数类型语法
|
||||
> 函数类型语法
|
||||
>
|
||||
<a name="function-type"></a>
|
||||
> *函数类型* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> [*函数类型子句*](#function-type-argument-clause) **throws**<sub>可选</sub> **->** [*类型*](#type)
|
||||
> *函数类型* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> [*函数类型子句*](#function-type-argument-clause) **rethrows** **->** [*类型*](#type)
|
||||
> *函数类型* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> [*函数类型子句*](#function-type-argument-clause) **throws**<sub>可选</sub> **->** [*类型*](#type)
|
||||
> *函数类型* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> [*函数类型子句*](#function-type-argument-clause) **rethrows** **->** [*类型*](#type)
|
||||
<a name="function-type-argument-clause"></a>
|
||||
> *函数类型子句* → ()
|
||||
> *函数类型子句* → ([*函数类型参数列表*](#function-type-argument-list)*...*<sub>可选</sub>)
|
||||
> *函数类型子句* → ()
|
||||
> *函数类型子句* → ([*函数类型参数列表*](#function-type-argument-list)*...*<sub>可选</sub>)
|
||||
<a name="function-type-argument-list"></a>
|
||||
> *函数类型参数列表* → [*函数类型参数*](function-type-argument) | [*函数类型参数*](function-type-argument), [*函数类型参数列表*](#function-type-argument-list)
|
||||
> *函数类型参数列表* → [*函数类型参数*](function-type-argument) | [*函数类型参数*](function-type-argument), [*函数类型参数列表*](#function-type-argument-list)
|
||||
<a name="function-type-argument"></a>
|
||||
> *函数类型参数* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> **输入输出参数**<sub>可选</sub> [*类型*](#type) | [*参数标签*](#argument-label) [*类型注解*](#type-annotation)
|
||||
> *函数类型参数* → [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> **输入输出参数**<sub>可选</sub> [*类型*](#type) | [*参数标签*](#argument-label) [*类型注解*](#type-annotation)
|
||||
<a name="argument-label"></a>
|
||||
> *参数标签* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
|
||||
@ -186,7 +241,8 @@ var array3D: [[[Int]]] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
|
||||
|
||||
关于 Swift 标准库中 `Array` 类型的详细讨论,请参阅 [数组](../chapter2/04_Collection_Types.html#arrays)。
|
||||
|
||||
> 数组类型语法
|
||||
> 数组类型语法
|
||||
>
|
||||
<a name="array-type"></a>
|
||||
> *数组类型* → **[** [*类型*](#type) **]**
|
||||
|
||||
@ -212,7 +268,8 @@ let someDictionary: Dictionary<String, Int> = ["Alex": 31, "Paul": 39]
|
||||
|
||||
关于 Swift 标准库中 `Dictionary` 类型的详细讨论,请参阅 [字典](../chapter2/04_Collection_Types.html#dictionaries)。
|
||||
|
||||
> 字典类型语法
|
||||
> 字典类型语法
|
||||
>
|
||||
<a name="dictionary-type"></a>
|
||||
> *字典类型* → **[** [*类型*](#type) **:** [*类型*](#type) **]**
|
||||
|
||||
@ -243,7 +300,8 @@ optionalInteger! // 42
|
||||
|
||||
更多细节以及更多如何使用可选类型的例子,请参阅 [可选类型](../chapter2/01_The_Basics.html#optionals)。
|
||||
|
||||
> 可选类型语法
|
||||
> 可选类型语法
|
||||
>
|
||||
<a name="optional-type"></a>
|
||||
> *可选类型* → [*类型*](#type) **?**
|
||||
|
||||
@ -277,7 +335,8 @@ let implicitlyUnwrappedArray: [Int]! // 正确
|
||||
|
||||
关于隐式解析可选类型的更多细节,请参阅 [隐式解析可选类型](../chapter2/01_The_Basics.html#implicityly_unwrapped_optionals)。
|
||||
|
||||
> 隐式解析可选类型语法
|
||||
> 隐式解析可选类型语法
|
||||
>
|
||||
<a name="implicitly-unwrapped-optional-type"></a>
|
||||
> *隐式解析可选类型* → [*类型*](#type) **!**
|
||||
|
||||
@ -294,7 +353,8 @@ let implicitlyUnwrappedArray: [Int]! // 正确
|
||||
|
||||
协议合成列表中的每项必须是协议名或协议合成类型的类型别名。
|
||||
|
||||
> 协议合成类型语法
|
||||
> 协议合成类型语法
|
||||
>
|
||||
<a name="protocol-composition-type"></a>
|
||||
> *协议合成类型* → [*协议标识符*](#protocol-identifier) & [*协议合成延续*](#protocol-composition-continuation)
|
||||
<a name="protocol-composition-continuation"></a>
|
||||
@ -329,16 +389,7 @@ type(of: someInstance).printClassName()
|
||||
// 打印 “SomeSubClass”
|
||||
```
|
||||
|
||||
可以使用恒等运算符(`===` 和 `!==`)来测试一个实例的运行时类型和它的编译时类型是否一致。
|
||||
|
||||
```swift
|
||||
if type(of: someInstance) === someInstance.self {
|
||||
print("The dynamic and static type of someInstance are the same")
|
||||
} else {
|
||||
print("The dynamic and static type of someInstance are different")
|
||||
}
|
||||
// 打印 "The dynamic and static type of someInstance are different"
|
||||
```
|
||||
更多信息可以查看Swift标准库里的`type(of:)`。
|
||||
|
||||
可以使用初始化表达式从某个类型的元类型构造出一个该类型的实例。对于类实例,被调用的构造器必须使用 `required` 关键字标记,或者整个类使用 `final` 关键字标记。
|
||||
|
||||
@ -356,7 +407,8 @@ let metatype: AnotherSubClass.Type = AnotherSubClass.self
|
||||
let anotherInstance = metatype.init(string: "some string")
|
||||
```
|
||||
|
||||
> 元类型语法
|
||||
> 元类型语法
|
||||
>
|
||||
<a name="metatype-type"></a>
|
||||
> *元类型* → [*类型*](#type) **.** **Type** | [*类型*](#type) **.** **Protocol**
|
||||
|
||||
@ -371,15 +423,14 @@ let anotherInstance = metatype.init(string: "some string")
|
||||
|
||||
枚举定义中的类型继承子句可以是一系列协议,或是枚举的原始值类型的命名型类型。在枚举定义中使用类型继承子句来指定原始值类型的例子,请参阅 [原始值](../chapter2/08_Enumerations.html#raw_values)。
|
||||
|
||||
> 类型继承子句语法
|
||||
> 类型继承子句语法
|
||||
>
|
||||
<a name="type_inheritance_clause"></a>
|
||||
> *类型继承子句* → **:** [*类要求*](#class-requirement) **,** [*类型继承列表*](#type-inheritance-list)
|
||||
> *类型继承子句* → **:** [*类要求*](#class-requirement)
|
||||
> *类型继承子句* → **:** [*类型继承列表*](#type-inheritance-list)
|
||||
<a name="type-inheritance-list"></a>
|
||||
> *类型继承列表* → [*类型标识符*](#type-identifier) | [*类型标识符*](#type-identifier) **,** [*类型继承列表*](#type-inheritance-list)
|
||||
<a name="class-requirement"></a>
|
||||
> *类要求* → **class**
|
||||
|
||||
|
||||
<a name="type_inference"></a>
|
||||
## 类型推断
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
> 校对:[175](https://github.com/Brian175)
|
||||
|
||||
> 3.0
|
||||
> 翻译+校对:[chenmingjia](https://github.com/chenmingjia)
|
||||
> 翻译+校对:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
|
||||
@ -48,7 +51,8 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
|
||||
|
||||
通过前缀表达式和二元表达式可以对简单表达式使用各种运算符。基本表达式从概念上讲是最简单的一种表达式,它是一种访问值的方式。后缀表达式则允许你建立复杂的表达式,例如函数调用和成员访问。每种表达式都在下面有详细论述。
|
||||
|
||||
> 表达式语法
|
||||
> 表达式语法
|
||||
>
|
||||
<a name="expression"></a>
|
||||
> *表达式* → [*try运算符*](#try-operator)<sub>可选</sub> [*前缀表达式*](#prefix-expression) [*二元表达式列表*](#binary-expressions)<sub>可选</sub>
|
||||
<a name="expression-list"></a>
|
||||
@ -65,7 +69,8 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
|
||||
|
||||
除了标准库运算符,你也可以对某个变量使用 `&` 运算符,从而将其传递给函数的输入输出参数。更多信息,请参阅 [输入输出参数](../chapter2/06_Functions.html#in_out_parameters)。
|
||||
|
||||
> 前缀表达式语法
|
||||
> 前缀表达式语法
|
||||
>
|
||||
<a name="prefix-expression"></a>
|
||||
> *前缀表达式* → [*前缀运算符*](02_Lexical_Structure.md#prefix-operator)<sub>可选</sub> [*后缀表达式*](#postfix-expression)
|
||||
> *前缀表达式* → [*输入输出表达式*](#in-out-expression)
|
||||
@ -73,7 +78,7 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
|
||||
> *输入输出表达式* → **&** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="try_operator"></a>
|
||||
### try 运算符
|
||||
### Try 运算符
|
||||
|
||||
try 表达式由 `try` 运算符加上紧随其后的可抛出错误的表达式组成,形式如下:
|
||||
|
||||
@ -102,7 +107,8 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
`try` 表达式不能出现在二进制运算符的的右侧,除非二进制运算符是赋值运算符或者 `try` 表达式是被圆括号括起来的。
|
||||
|
||||
关于 `try`、`try?` 和 `try!` 的更多信息,以及该如何使用的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.html)。
|
||||
> try 表达式语法
|
||||
> Try 表达式语法
|
||||
>
|
||||
<a name="try-operator"></a>
|
||||
> *try 运算符* → **try** | **try?** | **try!**
|
||||
|
||||
@ -117,11 +123,13 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
|
||||
关于 Swift 标准库提供的运算符的更多信息,请参阅 [*Swift Standard Library Operators Reference*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_StandardLibrary_Operators/index.html#//apple_ref/doc/uid/TP40016054)。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 在解析时,一个二元表达式将作为一个扁平列表表示,然后根据运算符的优先级,再进一步进行组合。例如,`2 + 3 * 5` 首先被看作具有五个元素的列表,即 `2`、`+`、`3`、`*`、`5`,随后根据运算符优先级组合为 `(2 + (3 * 5))`。
|
||||
|
||||
<a name="binary-expression"></a>
|
||||
> 二元表达式语法
|
||||
> 二元表达式语法
|
||||
>
|
||||
> *二元表达式* → [*二元运算符*](02_Lexical_Structure.md#binary-operator) [*前缀表达式*](#prefix-expression)
|
||||
> *二元表达式* → [*赋值运算符*](#assignment-operator) [*try运算符*](#try-operator)<sub>可选</sub> [*前缀表达式*](#prefix-expression)
|
||||
> *二元表达式* → [*条件运算符*](#conditional-operator) [*try运算符*](#try-operator)<sub>可选</sub> [*前缀表达式*](#prefix-expression)
|
||||
@ -145,7 +153,8 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
|
||||
赋值运算符不返回任何值。
|
||||
|
||||
> 赋值运算符语法
|
||||
> 赋值运算符语法
|
||||
>
|
||||
<a name="assignment-operator"></a>
|
||||
> *赋值运算符* → **=**
|
||||
|
||||
@ -160,7 +169,8 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
|
||||
关于使用三元条件运算符的例子,请参阅 [三元条件运算符](../chapter2/02_Basic_Operators.md#ternary_conditional_operator)。
|
||||
|
||||
> 三元条件运算符语法
|
||||
> 三元条件运算符语法
|
||||
>
|
||||
<a name="conditional-operator"></a>
|
||||
> *三元条件运算符* → **?** [try运算符](#try-operator)<sub>可选</sub> [*表达式*](#expression) **:**
|
||||
|
||||
@ -202,7 +212,8 @@ f(x as Any)
|
||||
关于类型转换的更多内容和例子,请参阅 [类型转换](../chapter2/19_Type_Casting.md)。
|
||||
|
||||
<a name="type-casting-operator"></a>
|
||||
> 类型转换运算符语法
|
||||
> 类型转换运算符语法
|
||||
>
|
||||
> *类型转换运算符* → **is** [*类型*](03_Types.md#type)
|
||||
> *类型转换运算符* → **as** [*类型*](03_Types.md#type)
|
||||
> *类型转换运算符* → **as** **?** [*类型*](03_Types.md#type)
|
||||
@ -213,7 +224,8 @@ f(x as Any)
|
||||
|
||||
基本表达式是最基本的表达式。它们可以单独使用,也可以跟前缀表达式、二元表达式、后缀表达式组合使用。
|
||||
|
||||
> 基本表达式语法
|
||||
> 基本表达式语法
|
||||
>
|
||||
<a name="primary-expression"></a>
|
||||
> *基本表达式* → [*标识符*](02_Lexical_Structure.md#identifier) [*泛型实参子句*](08_Generic_Parameters_and_Arguments.md#generic-argument-clause)<sub>可选</sub>
|
||||
> *基本表达式* → [*字面量表达式*](#literal-expression)
|
||||
@ -273,8 +285,8 @@ var emptyArray: [Double] = []
|
||||
var emptyDictionary: [String : Double] = [:]
|
||||
```
|
||||
|
||||
> 字面量表达式语法
|
||||
|
||||
> 字面量表达式语法
|
||||
>
|
||||
<a name="literal-expression"></a>
|
||||
> *字面量表达式* → [*字面量*](02_Lexical_Structure.md#literal)
|
||||
> *字面量表达式* → [*数组字面量*](#array-literal) | [*字典字面量*](#dictionary-literal)
|
||||
@ -295,7 +307,7 @@ var emptyDictionary: [String : Double] = [:]
|
||||
> *字典字面量项* → [*表达式*](#expression) **:** [*表达式*](#expression)
|
||||
|
||||
<a name="self_expression"></a>
|
||||
### self 表达式
|
||||
### Self 表达式
|
||||
|
||||
`self` 表达式是对当前类型或者当前实例的显式引用,它有如下形式:
|
||||
|
||||
@ -329,7 +341,8 @@ struct Point {
|
||||
}
|
||||
```
|
||||
|
||||
> self 表达式语法
|
||||
> Self 表达式语法
|
||||
>
|
||||
<a name="self-expression"></a>
|
||||
> *self 表达式* → **self** | [*self 方法表达式*](#self-method-expression) | [*self 下标表达式*](#self-subscript-expression) | [*self 构造器表达式*](#self-initializer-expression)
|
||||
>
|
||||
@ -341,9 +354,9 @@ struct Point {
|
||||
> *self 构造器表达式* → **self** **.** **init**
|
||||
|
||||
<a name="superclass_expression"></a>
|
||||
### 超类表达式
|
||||
### 父类表达式
|
||||
|
||||
超类表达式可以使我们在某个类中访问它的超类,它有如下形式:
|
||||
*父类*表达式可以使我们在某个类中访问它的超类,它有如下形式:
|
||||
|
||||
> super.`成员名称`
|
||||
> super[`下标索引`]
|
||||
@ -353,9 +366,11 @@ struct Point {
|
||||
|
||||
子类可以通过超类表达式在它们的成员、下标和构造器中使用超类中的实现。
|
||||
|
||||
> 超类表达式语法
|
||||
> 父类表达式语法
|
||||
>
|
||||
<a name="superclass-expression"></a>
|
||||
> *超类表达式* → [*超类方法表达式*](#superclass-method-expression) | [*超类下标表达式*](#superclass-subscript-expression) | [*超类构造器表达式*](#superclass-initializer-expression)
|
||||
> *超类表达式* → [*超类方法表达式*](#superclass-method-expression) | [*超类下标表达式*](#superclass-subscript-expression) | [*超类构造器表达式*](#superclass-initializer-expression)
|
||||
>
|
||||
<a name="superclass-method-expression"></a>
|
||||
> *超类方法表达式* → **super** **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="superclass-subscript-expression"></a>
|
||||
@ -366,7 +381,7 @@ struct Point {
|
||||
<a name="closure_expression"></a>
|
||||
### 闭包表达式
|
||||
|
||||
闭包表达式会创建一个闭包,在其他语言中也叫 *lambda* 或匿名函数。跟函数一样,闭包包含了待执行的代码,不同的是闭包还会捕获所在环境中的常量和变量。它的形式如下:
|
||||
闭包表达式会创建一个闭包,在其他语言中也叫 *lambda* 或*匿名*函数。跟函数一样,闭包包含了待执行的代码,不同的是闭包还会捕获所在环境中的常量和变量。它的形式如下:
|
||||
|
||||
```swift
|
||||
{ (parameters) -> return type in
|
||||
@ -400,7 +415,9 @@ myFunction { return $0 + $1 }
|
||||
myFunction { $0 + $1 }
|
||||
```
|
||||
|
||||
关于如何将闭包作为参数来传递的内容,请参阅 [函数调用表达式](#function_call_expression)。
|
||||
关于如何将闭包作为参数来传递的内容,请参阅 [函数调用表达式](#function_call_expression)。
|
||||
|
||||
关于逃逸闭包的内容,请参阅[逃逸闭包](./chapter2/07_Closures.md#escaping_closures)
|
||||
|
||||
#### 捕获列表
|
||||
|
||||
@ -460,8 +477,8 @@ myFunction { [weak parent = self.parent] in print(parent!.title) }
|
||||
|
||||
关于闭包表达式的更多信息和例子,请参阅 [闭包表达式](../chapter2/07_Closures.md#closure_expressions)。关于捕获列表的更多信息和例子,请参阅 [解决闭包引起的循环强引用](../chapter2/16_Automatic_Reference_Counting.md#resolving_strong_reference_cycles_for_closures)。
|
||||
|
||||
> 闭包表达式语法
|
||||
|
||||
> 闭包表达式语法
|
||||
>
|
||||
<a name="closure-expression"></a>
|
||||
> *闭包表达式* → **{** [*闭包签名*](#closure-signature)<sub>可选</sub> [*语句*](10_Statements.md#statements) **}**
|
||||
|
||||
@ -495,26 +512,38 @@ var x = MyEnumeration.SomeValue
|
||||
x = .AnotherValue
|
||||
```
|
||||
|
||||
> 隐式成员表达式语法
|
||||
> 隐式成员表达式语法
|
||||
>
|
||||
<a name="implicit-member-expression"></a>
|
||||
> *隐式成员表达式* → **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="parenthesized_expression"></a>
|
||||
### 圆括号表达式
|
||||
|
||||
*圆括号表达式*是由圆括号包围的表达式。你可以用圆括号说明成组的表达式的先后操作。成组的圆括号不会改变表达式的类型 - 例如`(1)`的类型就是简单的`Int`。
|
||||
|
||||
> 圆括号表达式语法
|
||||
>
|
||||
<a name="parenthesized-expression"></a>
|
||||
> *圆括号表达式* → **( [*表达式*](#expression) )**
|
||||
|
||||
<a name="Tuple_Expression"></a>
|
||||
### 元组表达式
|
||||
|
||||
圆括号表达式由圆括号和其中多个逗号分隔的子表达式组成。每个子表达式前面可以有一个标识符,用冒号隔开。圆括号表达式形式如下:
|
||||
元组表达式由圆括号和其中多个逗号分隔的子表达式组成。每个子表达式前面可以有一个标识符,用冒号隔开。元组表达式形式如下:
|
||||
|
||||
> (`标识符 1` : `表达式 1`, `标识符 2` : `表达式 2`, `...`)
|
||||
|
||||
使用圆括号表达式来创建元组,然后将其作为参数传递给函数。如果某个圆括号表达式中只有一个子表达式,那么它的类型就是子表达式的类型。例如,表达式 `(1)` 的类型是 `Int`,而不是 `(Int)`。
|
||||
元组表达式可以一个表达式都没有,也可以包含两个或是更多的表达式。单个表达式用括号括起来就是括号表达式了。
|
||||
|
||||
> 圆括号表达式语法
|
||||
<a name="parenthesized-expression"></a>
|
||||
> *圆括号表达式* → **(** [*表达式元素列表*](#expression-element-list)<sub>可选</sub> **)**
|
||||
<a name="expression-element-list"></a>
|
||||
> *表达式元素列表* → [*表达式元素*](#expression-element) | [*表达式元素*](#expression-element) **,** [*表达式元素列表*](#expression-element-list)
|
||||
<a name="expression-element"></a>
|
||||
> *表达式元素* → [*表达式*](#expression) | [*标识符*](02_Lexical_Structure.md#identifier) **:** [*表达式*](#expression)
|
||||
> 元组表达式语法
|
||||
>
|
||||
<a name="tuple-expression"></a>
|
||||
> *元组表达式* → **( )** | **(**[*元组元素*](#tuple-element), [*元组元素列表*](#tuple-element-list) **)**
|
||||
<a name="tuple-element-list"></a>
|
||||
> *元组元素列表* → [*元组元素*](#tuple-element) | [*元组元素*](#tuple-element) **,** [*元组元素列表*](#tuple-element-list)
|
||||
<a name="tuple-element"></a>
|
||||
> *元组元素* → [*表达式*](#expression) | [*标识符*](identifier) **:** [*表达式*](#expression)
|
||||
|
||||
<a name="wildcard_expression"></a>
|
||||
### 通配符表达式
|
||||
@ -526,7 +555,8 @@ x = .AnotherValue
|
||||
// x 为 10,20 被忽略
|
||||
```
|
||||
|
||||
> 通配符表达式语法
|
||||
> 通配符表达式语法
|
||||
>
|
||||
<a name="wildcard-expression"></a>
|
||||
> *通配符表达式* → **_**
|
||||
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
> 翻译:[chenmingbiao](https://github.com/chenmingbiao)
|
||||
|
||||
> 3.0
|
||||
> 翻译:[chenmingjia](https://github.com/chenmingjia)
|
||||
> 翻译:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
|
||||
@ -80,14 +83,15 @@
|
||||
`for-in` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
for 项 in 集合 {
|
||||
循环体语句
|
||||
for item in collection {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
`for-in` 语句在循环开始前会调用集合表达式的 `generate()` 方法来获取一个实现了 `GeneratorType` 协议的类型的值。接下来循环开始,反复调用该值的 `next()` 方法。如果其返回值不是 `None`,它将会被赋给“项”,然后执行循环体语句,执行完毕后回到循环开始处,继续重复这一过程;否则,既不会赋值也不会执行循环体语句,`for-in` 语句至此执行完毕。
|
||||
|
||||
> for-in 语句语法
|
||||
> for-in 语句语法
|
||||
>
|
||||
<a name="for-in-statement"></a>
|
||||
> *for-in 语句* → **for** **case**<sub>可选</sub> [*模式*](07_Patterns.md#pattern) **in** [*表达式*](04_Expressions.md#expression) [*where子句*](#where-clause)<sub>可选</sub> [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
@ -99,8 +103,8 @@ for 项 in 集合 {
|
||||
`while` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
while 条件 {
|
||||
语句
|
||||
while condition {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -113,24 +117,17 @@ while 条件 {
|
||||
|
||||
条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
|
||||
|
||||
> while 语句语法
|
||||
|
||||
> while 语句语法
|
||||
>
|
||||
<a name="while-statement"></a>
|
||||
> *while 语句* → **while** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
<a name="condition-clause"></a>
|
||||
> *条件子句* → [*表达式*](04_Expressions.md#expression)
|
||||
> *条件子句* → [*表达式*](04_Expressions.md#expression) **,** [*条件列表*](#condition-list)
|
||||
> *条件子句* → [*条件列表*](#condition-list)
|
||||
> *条件子句* → [*可用性条件*](#availability-condition) **,** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="condition-list"></a>
|
||||
> *条件列表* → [*条件*](#condition) | [*条件*](#condition) **,** [*条件列表*](#condition-list)
|
||||
> *条件子句* → [*表达式*](04_Expressions.md#expression) | [*表达式*](04_Expressions.md#expression) **,** [*条件列表*](#condition-list)
|
||||
<a name="condition"></a>
|
||||
> *条件* → [*表达式*](04_Expressions.md#expression) |[*可用性条件*](#availability-condition) | [*case条件*](#case-condition) | [*可选绑定条件*](#optional-binding-condition)
|
||||
<a name="case-condition"></a>
|
||||
> *case 条件* → **case** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer)
|
||||
|
||||
<a name="optional-binding-condition"></a>
|
||||
> *可选绑定条件* → **let** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer) | **var** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer)
|
||||
|
||||
@ -143,8 +140,8 @@ while 条件 {
|
||||
|
||||
```swift
|
||||
repeat {
|
||||
语句
|
||||
} while 条件
|
||||
statements
|
||||
} while condition
|
||||
```
|
||||
|
||||
`repeat-while` 语句的执行流程如下:
|
||||
@ -156,7 +153,8 @@ repeat {
|
||||
|
||||
条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
|
||||
|
||||
> repeat-while 语句语法
|
||||
> repeat-while 语句语法
|
||||
>
|
||||
<a name="repeat-while-statement"></a>
|
||||
> *repeat-while 语句* → **repeat** [*代码块*](05_Declarations.md#code-block) **while** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
@ -167,7 +165,8 @@ repeat {
|
||||
|
||||
`if` 语句和 `switch` 语句中的控制流可以用 `break` 语句改变,请参阅 [Break 语句](#break_statement)。
|
||||
|
||||
> 分支语句语法
|
||||
> 分支语句语法
|
||||
>
|
||||
<a name="branch-statement"></a>
|
||||
> *分支语句* → [*if 语句*](#if-statement)
|
||||
> *分支语句* → [*guard 语句*](#guard-statement)
|
||||
@ -183,36 +182,37 @@ repeat {
|
||||
第一种形式是当且仅当条件为真时执行代码,像下面这样:
|
||||
|
||||
```swift
|
||||
if 条件 {
|
||||
语句
|
||||
if condition {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
第二种形式是在第一种形式的基础上添加 `else` 语句,当只有一个 `else` 语句时,像下面这样:
|
||||
|
||||
```swift
|
||||
if 条件 {
|
||||
若条件为真则执行这部分语句
|
||||
if ondition {
|
||||
statements to execute if condition is true
|
||||
} else {
|
||||
若条件为假则执行这部分语句
|
||||
statements to execute if condition is false
|
||||
}
|
||||
```
|
||||
|
||||
`else` 语句也可包含 `if` 语句,从而形成一条链来测试更多的条件,像下面这样:
|
||||
|
||||
```swift
|
||||
if 条件1 {
|
||||
若条件1为真则执行这部分语句
|
||||
} else if 条件2 {
|
||||
若条件2为真则执行这部分语句
|
||||
} else {
|
||||
若前两个条件均为假则执行这部分语句
|
||||
}
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
`if` 语句中条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
|
||||
|
||||
> if 语句语法
|
||||
> if 语句语法
|
||||
>
|
||||
<a name="if-statement"></a>
|
||||
> *if 语句* → **if** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block) [*else子句*](#else-clause)<sub>可选</sub>
|
||||
<a name="else-clause"></a>
|
||||
@ -226,8 +226,8 @@ if 条件1 {
|
||||
`guard` 语句的格式如下:
|
||||
|
||||
```swift
|
||||
guard 条件 else {
|
||||
语句
|
||||
guard condition else {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -244,7 +244,8 @@ guard 条件 else {
|
||||
|
||||
关于控制转移语句,请参阅 [控制转移语句](#control_transfer_statements)。关于`Never`返回类型的函数,请参阅 [永不返回的函数](05_Declarations.md#rethrowing_functions_and_methods)。
|
||||
|
||||
> guard 语句语法
|
||||
> guard 语句语法
|
||||
>
|
||||
<a name="guard-statement"></a>
|
||||
> *guard 语句* → **guard** [*条件子句*](#condition-clause) **else** [*代码块*](05_Declarations.html#code-block)
|
||||
|
||||
@ -256,19 +257,20 @@ guard 条件 else {
|
||||
`switch` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
switch 控制表达式 {
|
||||
case 模式1:
|
||||
语句
|
||||
case 模式2 where 条件:
|
||||
语句
|
||||
case 模式3 where 条件, 模式4 where 条件:
|
||||
语句
|
||||
default:
|
||||
语句
|
||||
}
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
`switch` 语句会先计算控制表达式的值,然后与每一个 `case` 的模式进行匹配。如果匹配成功,程序将会执行对应的 `case` 中的语句。另外,每一个 `case` 都不能为空,也就是说在每一个 `case` 中必须至少有一条语句。如果你不想在匹配到的 `case` 中执行代码,只需在该 `case` 中写一条 `break` 语句即可。
|
||||
`switch` 语句会先计算*控制表达式*的值,然后与每一个 `case` 的模式进行匹配。如果匹配成功,程序将会执行对应的 `case` 中的语句。另外,每一个 `case` 都不能为空,也就是说在每一个 `case` 中必须至少有一条语句。如果你不想在匹配到的 `case` 中执行代码,只需在该 `case` 中写一条 `break` 语句即可。
|
||||
|
||||
可以用作控制表达式的值是十分灵活的。除了标量类型外,如 `Int`、`Character`,你可以使用任何类型的值,包括浮点数、字符串、元组、自定义类型的实例和可选类型。控制表达式的值还可以用来匹配枚举类型中的成员值或是检查该值是否包含在指定的 `Range` 中。关于如何在 `switch` 语句中使用这些类型,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章中的 [Switch](../chapter2/05_Control_Flow.html#switch)。
|
||||
|
||||
@ -292,8 +294,8 @@ case let (x, y) where x == y:
|
||||
|
||||
当匹配到的 `case` 中的代码执行完毕后,`switch` 语句会直接退出,而不会继续执行下一个 `case` 。这就意味着,如果你想执行下一个 `case`,需要显式地在当前 `case` 中使用 `fallthrough` 语句。关于 `fallthrough` 语句的更多信息,请参阅 [Fallthrough 语句](#fallthrough_statements)。
|
||||
|
||||
> switch 语句语法
|
||||
|
||||
> switch 语句语法
|
||||
>
|
||||
<a name="switch-statement"></a>
|
||||
> *switch 语句* → **switch** [*表达式*](04_Expressions.md#expression) **{** [*switch-case列表*](#switch-cases)<sub>可选</sub> **}**
|
||||
<a name="switch-cases"></a>
|
||||
@ -322,7 +324,8 @@ case let (x, y) where x == y:
|
||||
|
||||
关于使用带标签的语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章中的 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
|
||||
|
||||
> 带标签的语句语法
|
||||
> 带标签的语句语法
|
||||
>
|
||||
<a name="labeled-statement"></a>
|
||||
> *带标签的语句* → [*语句标签*](#statement-label) [*循环语句*](#loop-statement) | [*语句标签*](#statement-label) [*if语句*](#if-statement) | [*语句标签*](#statement-label) [*switch语句*](#switch-statement)
|
||||
<a name="statement-label"></a>
|
||||
@ -335,7 +338,8 @@ case let (x, y) where x == y:
|
||||
|
||||
控制转移语句能够无条件地把控制权从一片代码转移到另一片代码,从而改变代码执行的顺序。Swift 提供五种类型的控制转移语句:`break` 语句、`continue` 语句、`fallthrough` 语句、`return` 语句和 `throw` 语句。
|
||||
|
||||
> 控制转移语句语法
|
||||
> 控制转移语句语法
|
||||
>
|
||||
<a name="control-transfer-statement"></a>
|
||||
> *控制转移语句* → [*break 语句*](#break-statement)
|
||||
> *控制转移语句* → [*continue 语句*](#continue-statement)
|
||||
@ -349,7 +353,7 @@ case let (x, y) where x == y:
|
||||
`break` 语句用于终止循环语句、`if` 语句或 `switch` 语句的执行。使用 `break` 语句时,可以只写 `break` 这个关键词,也可以在 `break` 后面跟上标签名,像下面这样:
|
||||
|
||||
> break
|
||||
> break `标签名`
|
||||
> break `label name`
|
||||
|
||||
当 `break` 语句后面带标签名时,可用于终止由这个标签标记的循环语句、`if` 语句或 `switch` 语句的执行。
|
||||
|
||||
@ -359,7 +363,8 @@ case let (x, y) where x == y:
|
||||
|
||||
关于使用 `break` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [Break](../chapter2/05_Control_Flow.md#break) 和 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
|
||||
|
||||
> break 语句语法
|
||||
> break 语句语法
|
||||
>
|
||||
<a name="break-statement"></a>
|
||||
> *break 语句* → **break** [*标签名称*](#label-name)<sub>可选</sub>
|
||||
|
||||
@ -369,7 +374,7 @@ case let (x, y) where x == y:
|
||||
`continue` 语句用于终止循环中当前迭代的执行,但不会终止该循环的执行。使用 `continue` 语句时,可以只写 `continue` 这个关键词,也可以在 `continue` 后面跟上标签名,像下面这样:
|
||||
|
||||
> continue
|
||||
> continue `标签名`
|
||||
> continue `label name`
|
||||
|
||||
当 `continue` 语句后面带标签名时,可用于终止由这个标签标记的循环中当前迭代的执行。
|
||||
|
||||
@ -381,7 +386,8 @@ case let (x, y) where x == y:
|
||||
|
||||
关于使用 `continue` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [Continue](../chapter2/05_Control_Flow.md#continue) 和 [带标签的语句](../chapter2/05_Control_Flow.md#labeled_statements)。
|
||||
|
||||
> continue 语句语法
|
||||
> continue 语句语法
|
||||
>
|
||||
<a name="continue-statement"></a>
|
||||
> *continue 语句* → **continue** [*标签名称*](#label-name)<sub>可选</sub>
|
||||
|
||||
@ -394,7 +400,8 @@ case let (x, y) where x == y:
|
||||
|
||||
关于在 `switch` 语句中使用 `fallthrough` 语句的例子,请参阅 [控制流](../chapter2/05_Control_Flow.md) 一章的 [控制转移语句](../chapter2/05_Control_Flow.md#control_transfer_statements)。
|
||||
|
||||
> fallthrough 语句语法
|
||||
> fallthrough 语句语法
|
||||
>
|
||||
<a name="fallthrough-statement"></a>
|
||||
> *fallthrough 语句* → **fallthrough**
|
||||
|
||||
@ -406,16 +413,18 @@ case let (x, y) where x == y:
|
||||
使用 `return` 语句时,可以只写 `return` 这个关键词,也可以在 `return` 后面跟上表达式,像下面这样:
|
||||
|
||||
> return
|
||||
> return `表达式`
|
||||
> return `expression`
|
||||
|
||||
当 `return` 语句后面带表达式时,表达式的值将会返回给调用函数或方法。如果表达式的值的类型与函数或者方法声明的返回类型不匹配,Swift 则会在返回表达式的值之前将表达式的值的类型转换为返回类型。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 正如 [可失败构造器](05_Declarations.md#failable_initializers) 中所描述的,`return nil` 在可失败构造器中用于表明构造失败。
|
||||
|
||||
而只写 `return` 时,仅仅是从该函数或方法中返回,而不返回任何值(也就是说,函数或方法的返回类型为 `Void` 或者说 `()`)。
|
||||
|
||||
> return 语句语法
|
||||
> return 语句语法
|
||||
>
|
||||
<a name="return-statement"></a>
|
||||
> *return 语句* → **return** [*表达式*](04_Expressions.html#expression)<sub>可选</sub>
|
||||
|
||||
@ -428,13 +437,14 @@ case let (x, y) where x == y:
|
||||
|
||||
`throw` 语句由 `throw` 关键字紧跟一个表达式组成,如下所示:
|
||||
|
||||
> throw `表达式`
|
||||
> throw `expression`
|
||||
|
||||
表达式的结果必须符合 `ErrorType` 协议。
|
||||
|
||||
关于如何使用 `throw` 语句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md) 一章的 [用 throwing 函数传递错误](../chapter2/18_Error_Handling.md#propagating_errors_using_throwing_functions)。
|
||||
|
||||
> throw 语句语法
|
||||
> throw 语句语法
|
||||
>
|
||||
<a name="throw-statement"></a>
|
||||
> *throw 语句* → **throw** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
@ -447,7 +457,7 @@ case let (x, y) where x == y:
|
||||
|
||||
```swift
|
||||
defer {
|
||||
语句
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -469,7 +479,8 @@ f()
|
||||
|
||||
`defer` 语句中的语句无法将控制权转移到 `defer` 语句外部。
|
||||
|
||||
> defer 语句语法
|
||||
> defer 语句语法
|
||||
>
|
||||
<a name="defer-statement"></a>
|
||||
> *延迟语句* → **defer** [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
@ -483,13 +494,13 @@ Swift 中的 `do` 语句与 C 中限定代码块界限的大括号(`{}`)很
|
||||
`do` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
do {
|
||||
try 表达式
|
||||
语句
|
||||
} catch 模式1 {
|
||||
语句
|
||||
} catch 模式2 where 条件 {
|
||||
语句
|
||||
do {
|
||||
try expression
|
||||
statements
|
||||
} catch pattern 1 {
|
||||
statements
|
||||
} catch pattern 2 where condition {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -499,7 +510,8 @@ do {
|
||||
|
||||
关于如何在 `do` 语句中使用一系列 `catch` 子句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md#handling_errors)。
|
||||
|
||||
> do 语句语法
|
||||
> do 语句语法
|
||||
>
|
||||
<a name="do-statement"></a>
|
||||
> *do 语句* → **do** [*代码块*](05_Declarations.md#code-block) [*多条 catch子句*](#catch-clauses)<sub>可选</sub>
|
||||
<a name="catch-clauses"></a>
|
||||
@ -512,7 +524,8 @@ do {
|
||||
|
||||
编译器控制语句允许程序改变编译器的行为。Swift 有两种编译器控制语句:编译配置语句和线路控制语句。
|
||||
|
||||
> 编译器控制语句语法
|
||||
> 编译器控制语句语法
|
||||
>
|
||||
<a name="compiler-control-statement"></a>
|
||||
> *编译器控制语句* → [*编译配置语句*](#build-config-statement)
|
||||
> *编译器控制语句* → [*线路控制语句*](#line-control-statement)
|
||||
@ -525,8 +538,8 @@ do {
|
||||
每一个编译配置语句都以 `#if` 开始,`#endif` 结束。如下是一个简单的编译配置语句:
|
||||
|
||||
```swift
|
||||
#if 编译配置项
|
||||
语句
|
||||
#if compilation condition
|
||||
statements
|
||||
#endif
|
||||
```
|
||||
|
||||
@ -542,7 +555,8 @@ do {
|
||||
|
||||
`swift()`(语言版本检测函数)的版本号参数主要由主版本号和次版本号组成并且使用点号(`.`)分隔开,`>=` 和版本号之间不能有空格。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> `arch(arm)` 平台检测函数在 ARM 64 位设备上不会返回 `true`。如果代码在 32 位的 iOS 模拟器上编译,`arch(i386)` 平台检测函数会返回 `true`。
|
||||
|
||||
你可以使用逻辑操作符 `&&`、`||` 和 `!` 来组合多个编译配置,还可以使用圆括号来进行分组。
|
||||
@ -550,21 +564,22 @@ do {
|
||||
就像 `if` 语句一样,你可以使用 `#elseif` 子句来添加任意多个条件分支来测试不同的编译配置。你也可以使用 `#else` 子句来添加最终的条件分支。包含多个分支的编译配置语句例子如下:
|
||||
|
||||
```swift
|
||||
#if 编译配置1
|
||||
如果编译配置1成立则执行这部分代码
|
||||
#elseif 编译配置2
|
||||
如果编译配置2成立则执行这部分代码
|
||||
#else
|
||||
如果编译配置均不成立则执行这部分代码
|
||||
#if compilation condition 1
|
||||
statements to compile if compilation condition 1 is true
|
||||
#elseif compilation condition 2
|
||||
statements to compile if compilation condition 2 is true
|
||||
#else
|
||||
statements to compile if both compilation conditions are false
|
||||
#endif
|
||||
```
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 即使没有被编译,编译配置中的语句仍然会被解析。然而,唯一的例外是编译配置语句中包含语言版本检测函数:仅当 `Swift` 编译器版本和语言版本检测函数中指定的版本号匹配时,语句才会被解析。这种设定能确保旧的编译器不会尝试去解析新 Swift 版本的语法。
|
||||
|
||||
<a name="build-config-statement"></a>
|
||||
> 编译配置语句语法
|
||||
|
||||
> 编译配置语句语法
|
||||
>
|
||||
<a name="build-configuration-statement"></a>
|
||||
> *单个编译配置语句* → **#if** [*编译配置*](#build-configuration) [*语句*](#statements)<sub>可选</sub> [*多个编译配置elseif子句*](#build-configuration-elseif-clauses)<sub>可选</sub> **-** [*单个编译配置else子句*](#build-configuration-else-clause)<sub>可选</sub> **#endif**
|
||||
<a name="build-configuration-elseif-clauses"></a>
|
||||
@ -603,7 +618,7 @@ do {
|
||||
|
||||
行控制语句形式如下:
|
||||
|
||||
> \#sourceLocation(file: `文件名` , line:`行号`)
|
||||
> \#sourceLocation(file: `filename` , line:`line number`)
|
||||
|
||||
> \#sourceLocation()
|
||||
|
||||
@ -612,8 +627,8 @@ do {
|
||||
第二种的行控制语句,`#sourceLocation()`,会将源代码的定位信息重置回默认的行号和文件名。
|
||||
|
||||
<a name="line-control-statement"></a>
|
||||
> 行控制语句语法
|
||||
|
||||
> 行控制语句语法
|
||||
>
|
||||
> *行控制语句* → **#sourceLocation(file:[*文件名*](#file-name),line:[*行号*](#line-number))**
|
||||
> *行控制语句* → **#sourceLocation()**
|
||||
<a name="line-number"></a>
|
||||
@ -629,11 +644,11 @@ do {
|
||||
可用性条件的形式如下:
|
||||
|
||||
```swift
|
||||
if #available(平台名称 版本, ..., *) {
|
||||
如果 API 可用,则执行这部分语句
|
||||
} else {
|
||||
如果 API 不可用,则执行这部分语句
|
||||
}
|
||||
if #available(platform name version, ..., *) {
|
||||
statements to execute if the APIs are available
|
||||
} else {
|
||||
fallback statements to execute if the APIs are unavailable
|
||||
}
|
||||
```
|
||||
|
||||
使用可用性条件来执行一个代码块时,取决于使用的 API 在运行时是否可用,编译器会根据可用性条件提供的信息来决定是否执行相应的代码块。
|
||||
@ -642,8 +657,8 @@ if #available(平台名称 版本, ..., *) {
|
||||
|
||||
与布尔类型的条件不同,不能用逻辑运算符 `&&` 和 `||` 组合可用性条件。
|
||||
|
||||
> 可用性条件语法
|
||||
|
||||
> 可用性条件语法
|
||||
>
|
||||
<a name="availability-condition"></a>
|
||||
> *可用性条件* → **#available** **(** [*可用性参数列表*](#availability-arguments) **)**
|
||||
<a name="availability-arguments"></a>
|
||||
Reference in New Issue
Block a user