翻译细节与 markdown 统一格式修改 (#779)
* 修正全角逗号、句号的使用 * 修正逗号使用 * 修正一处代码空格错误 * 修正斜体范围,引用的空格使用 * 修正示例代码错误 * 修正标点,修正示例代码 * 修正标点 * 修正标点 * 添加 Swift 3.1 的更新 * 修改 Swift 3.0.1 位置 * 添加 Swift 4.0.3 更新 * 添加 Swift 4.1 更新 * 修正示例代码 * 修正 markdown 引用语法,优化翻译语句 * 修正示例代码 * 修正标点使用,优化翻译语句 * 修正示例代码 * 修正示例代码 * 优化翻译语句,修正示例代码语法 * 更新示例代码以符合 Swift 4.1 * 优化 markdown 引用格式的使用 * 优化 markdown 行内代码块使用,代码块与正文使用空格分隔 * 人工校验 markdown 行内代码块使用 * 中英文空格分隔 * 移除行末空格 * 人工校验 markdown 行内代码块使用 * 修正 markdown 无序列表使用
This commit is contained in:
@ -34,12 +34,12 @@ Swift 语言相对较小,这是由于 Swift 代码中在各种地方出现的
|
||||
举个例子,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 方法块 → { [*getter 子句*](05_Declarations.html#getter-clause) [*setter 子句*](05_Declarations.html#setter-clause)<sub>可选</sub> }
|
||||
> 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) }
|
||||
|
||||
@ -42,26 +42,26 @@ Swift 的*“词法结构 (lexical structure)”* 描述了能构成该语言中
|
||||
> 空白语法
|
||||
|
||||
<a id="whitespace"></a>
|
||||
> *空白* → [*空白项*](#whitespace-item) [*空白*](#whitespace)<sub>可选</sub>
|
||||
> *空白项* → [*断行符*](#line-break)
|
||||
> *空白项* → [*注释*](#comment)
|
||||
> *空白项* → [*多行注释*](#multiline-comment)
|
||||
> *空白* → [*空白项*](#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+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标量值, 除了 `/*` 或者 `*/`
|
||||
<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) 所述。
|
||||
|
||||
@ -77,40 +77,40 @@ Swift 的*“词法结构 (lexical structure)”* 描述了能构成该语言中
|
||||
> 标识符语法
|
||||
|
||||
<a id="identifier"></a>
|
||||
> *标识符* → [*头部标识符*](#identifier-head) [*标识符字符组*](#identifier-characters)<sub>可选</sub>
|
||||
> *标识符* → \`[*头部标识符*](#identifier-head) [*标识符字符组*](#identifier-characters)<sub>可选</sub>\`
|
||||
> *标识符* → [*隐式参数名*](#implicit-parameter-name)
|
||||
> *标识符* → [*头部标识符*](#identifier-head) [*标识符字符组*](#identifier-characters)<sub>可选</sub>
|
||||
> *标识符* → \`[*头部标识符*](#identifier-head) [*标识符字符组*](#identifier-characters)<sub>可选</sub>\`
|
||||
> *标识符* → [*隐式参数名*](#implicit-parameter-name)
|
||||
|
||||
<a id="identifier-list"></a>
|
||||
> *标识符列表* → [*标识符*](#identifier) | [*标识符*](#identifier) **,** [*标识符列表*](#identifier-list)
|
||||
|
||||
<a id="identifier-head"></a>
|
||||
> *头部标识符* → 大写或小写字母 A - Z
|
||||
> *头部标识符* → _
|
||||
> *头部标识符* → U+00A8,U+00AA,U+00AD,U+00AF,U+00B2–U+00B5,或者 U+00B7–U+00BA
|
||||
> *头部标识符* → U+00BC–U+00BE,U+00C0–U+00D6,U+00D8–U+00F6,或者 U+00F8–U+00FF
|
||||
> *头部标识符* → U+0100–U+02FF,U+0370–U+167F,U+1681–U+180D,或者 U+180F–U+1DBF
|
||||
> *头部标识符* → U+1E00–U+1FFF
|
||||
> *头部标识符* → U+200B–U+200D,U+202A–U+202E,U+203F–U+2040,U+2054,或者 U+2060–U+206F
|
||||
> *头部标识符* → U+2070–U+20CF,U+2100–U+218F,U+2460–U+24FF,或者 U+2776–U+2793
|
||||
> *头部标识符* → U+2C00–U+2DFF 或者 U+2E80–U+2FFF
|
||||
> *头部标识符* → U+3004–U+3007,U+3021–U+302F,U+3031–U+303F,或者 U+3040–U+D7FF
|
||||
> *头部标识符* → U+F900–U+FD3D,U+FD40–U+FDCF,U+FDF0–U+FE1F,或者 U+FE30–U+FE44
|
||||
> *头部标识符* → U+FE47–U+FFFD
|
||||
> *头部标识符* → U+10000–U+1FFFD,U+20000–U+2FFFD,U+30000–U+3FFFD,或者 U+40000–U+4FFFD
|
||||
> *头部标识符* → U+50000–U+5FFFD,U+60000–U+6FFFD,U+70000–U+7FFFD,或者 U+80000–U+8FFFD
|
||||
> *头部标识符* → U+90000–U+9FFFD,U+A0000–U+AFFFD,U+B0000–U+BFFFD,或者 U+C0000–U+CFFFD
|
||||
> *头部标识符* → U+D0000–U+DFFFD 或者 U+E0000–U+EFFFD
|
||||
<a id="identifier-head"></a>
|
||||
> *头部标识符* → 大写或小写字母 A - Z
|
||||
> *头部标识符* → _
|
||||
> *头部标识符* → U+00A8,U+00AA,U+00AD,U+00AF,U+00B2–U+00B5,或者 U+00B7–U+00BA
|
||||
> *头部标识符* → U+00BC–U+00BE,U+00C0–U+00D6,U+00D8–U+00F6,或者 U+00F8–U+00FF
|
||||
> *头部标识符* → U+0100–U+02FF,U+0370–U+167F,U+1681–U+180D,或者 U+180F–U+1DBF
|
||||
> *头部标识符* → U+1E00–U+1FFF
|
||||
> *头部标识符* → U+200B–U+200D,U+202A–U+202E,U+203F–U+2040,U+2054,或者 U+2060–U+206F
|
||||
> *头部标识符* → U+2070–U+20CF,U+2100–U+218F,U+2460–U+24FF,或者 U+2776–U+2793
|
||||
> *头部标识符* → U+2C00–U+2DFF 或者 U+2E80–U+2FFF
|
||||
> *头部标识符* → U+3004–U+3007,U+3021–U+302F,U+3031–U+303F,或者 U+3040–U+D7FF
|
||||
> *头部标识符* → U+F900–U+FD3D,U+FD40–U+FDCF,U+FDF0–U+FE1F,或者 U+FE30–U+FE44
|
||||
> *头部标识符* → U+FE47–U+FFFD
|
||||
> *头部标识符* → U+10000–U+1FFFD,U+20000–U+2FFFD,U+30000–U+3FFFD,或者 U+40000–U+4FFFD
|
||||
> *头部标识符* → U+50000–U+5FFFD,U+60000–U+6FFFD,U+70000–U+7FFFD,或者 U+80000–U+8FFFD
|
||||
> *头部标识符* → U+90000–U+9FFFD,U+A0000–U+AFFFD,U+B0000–U+BFFFD,或者 U+C0000–U+CFFFD
|
||||
> *头部标识符* → U+D0000–U+DFFFD 或者 U+E0000–U+EFFFD
|
||||
|
||||
<a id="identifier-character"></a>
|
||||
> *标识符字符* → 数值 0 - 9
|
||||
> *标识符字符* → U+0300–U+036F,U+1DC0–U+1DFF,U+20D0–U+20FF,或者 U+FE20–U+FE2F
|
||||
> *标识符字符* → 数值 0 - 9
|
||||
> *标识符字符* → U+0300–U+036F,U+1DC0–U+1DFF,U+20D0–U+20FF,或者 U+FE20–U+FE2F
|
||||
> *标识符字符* → [*头部标识符*](#identifier-head)
|
||||
> <a id="identifier-characters"></a>
|
||||
> *标识符字符组* → [*标识符字符*](#identifier-character) [*标识符字符组*](#identifier-characters)<sub>可选</sub>
|
||||
> <a id="identifier-characters"></a>
|
||||
> *标识符字符组* → [*标识符字符*](#identifier-character) [*标识符字符组*](#identifier-characters)<sub>可选</sub>
|
||||
|
||||
<a id="implicit-parameter-name"></a>
|
||||
> *隐式参数名* → **$** [*十进制数字列表*](#decimal-digits)
|
||||
<a id="implicit-parameter-name"></a>
|
||||
> *隐式参数名* → **$** [*十进制数字列表*](#decimal-digits)
|
||||
|
||||
<a id="keywords"></a>
|
||||
## 关键字和标点符号
|
||||
@ -145,13 +145,13 @@ true // 布尔值字面量
|
||||
当为一个字面量值指定了类型标注的时候,这个标注的类型必须能通过这个字面量值实例化。也就是说,这个类型必须符合这些 Swift 标准库协议中的一个:整数字面量的 `IntegerLiteralConvertible` 协议、浮点数字面量的 `FloatingPointLiteralConvertible` 协议、字符串字面量的 `StringLiteralConvertible` 协议以及布尔值字面量的 `BooleanLiteralConvertible` 协议。比如,`Int8` 符合 `IntegerLiteralConvertible` 协议,因此它能在 `let x: Int8 = 42` 这个声明中作为整数字面量 `42` 的类型标注。
|
||||
|
||||
> 字面量语法
|
||||
>
|
||||
> *字面量* → [*数值字面量*](#numeric-literal) | [*字符串字面量*](#string-literal) | [*布尔值字面量*](#boolean-literal) | [*nil 字面量*](#nil-literal)
|
||||
>
|
||||
> *字面量* → [*数值字面量*](#numeric-literal) | [*字符串字面量*](#string-literal) | [*布尔值字面量*](#boolean-literal) | [*nil 字面量*](#nil-literal)
|
||||
|
||||
<a id="numeric-literal"></a>
|
||||
> *数值字面量* → **-**<sub>可选</sub> [*整数字面量*](#integer-literal) | **-**<sub>可选</sub> [*浮点数字面量*](#floating-point-literal)
|
||||
<a id="numeric-literal"></a>
|
||||
> *数值字面量* → **-**<sub>可选</sub> [*整数字面量*](#integer-literal) | **-**<sub>可选</sub> [*浮点数字面量*](#floating-point-literal)
|
||||
> <a id="boolean-literal"></a>
|
||||
> *布尔值字面量* → **true** | **false**
|
||||
> *布尔值字面量* → **true** | **false**
|
||||
> <a id="nil-literal"></a>
|
||||
> *nil 字面量* → **nil**
|
||||
|
||||
@ -168,51 +168,51 @@ true // 布尔值字面量
|
||||
|
||||
除非特别指定,整数字面量的默认推导类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数](../chapter2/01_The_Basics.html#integers)。
|
||||
|
||||
> 整数字面量语法
|
||||
> 整数字面量语法
|
||||
>
|
||||
<a id="integer-literal"></a>
|
||||
> *整数字面量* → [*二进制字面量*](#binary-literal)
|
||||
> *整数字面量* → [*八进制字面量*](#octal-literal)
|
||||
> *整数字面量* → [*十进制字面量*](#decimal-literal)
|
||||
> *整数字面量* → [*十六进制字面量*](#hexadecimal-literal)
|
||||
> *整数字面量* → [*二进制字面量*](#binary-literal)
|
||||
> *整数字面量* → [*八进制字面量*](#octal-literal)
|
||||
> *整数字面量* → [*十进制字面量*](#decimal-literal)
|
||||
> *整数字面量* → [*十六进制字面量*](#hexadecimal-literal)
|
||||
|
||||
<a id="binary-literal"></a>
|
||||
> *二进制字面量* → **0b** [*二进制数字*](#binary-digit) [*二进制字面量字符组*](#binary-literal-characters)<sub>可选</sub>
|
||||
> <a id="binary-digit"></a>
|
||||
> *二进制数字* → 数值 0 到 1
|
||||
> <a id="binary-digit"></a>
|
||||
> *二进制数字* → 数值 0 到 1
|
||||
> <a id="binary-literal-character"></a>
|
||||
> *二进制字面量字符* → [*二进制数字*](#binary-digit) | _
|
||||
> *二进制字面量字符* → [*二进制数字*](#binary-digit) | _
|
||||
> <a id="binary-literal-characters"></a>
|
||||
> *二进制字面量字符组* → [*二进制字面量字符*](#binary-literal-character) [*二进制字面量字符组*](#binary-literal-characters)<sub>可选</sub>
|
||||
> *二进制字面量字符组* → [*二进制字面量字符*](#binary-literal-character) [*二进制字面量字符组*](#binary-literal-characters)<sub>可选</sub>
|
||||
|
||||
<a id="octal-literal"></a>
|
||||
> *八进制字面量* → **0o** [*八进字数字*](#octal-digit) [*八进制字符组*](#octal-literal-characters)<sub>可选</sub>
|
||||
> <a id="octal-digit"></a>
|
||||
> *八进字数字* → 数值 0 到 7
|
||||
<a id="octal-literal"></a>
|
||||
> *八进制字面量* → **0o** [*八进字数字*](#octal-digit) [*八进制字符组*](#octal-literal-characters)<sub>可选</sub>
|
||||
> <a id="octal-digit"></a>
|
||||
> *八进字数字* → 数值 0 到 7
|
||||
> <a id="octal-literal-character"></a>
|
||||
> *八进制字符* → [*八进字数字*](#octal-digit) | _
|
||||
> *八进制字符* → [*八进字数字*](#octal-digit) | _
|
||||
> <a id="octal-literal-characters"></a>
|
||||
> *八进制字符组* → [*八进制字符*](#octal-literal-character) [*八进制字符组*](#octal-literal-characters)<sub>可选</sub>
|
||||
|
||||
<a id="decimal-literal"></a>
|
||||
> *十进制字面量* → [*十进制数字*](#decimal-digit) [*十进制字符组*](#decimal-literal-characters)<sub>可选</sub>
|
||||
<a id="decimal-literal"></a>
|
||||
> *十进制字面量* → [*十进制数字*](#decimal-digit) [*十进制字符组*](#decimal-literal-characters)<sub>可选</sub>
|
||||
> <a id="decimal-digit"></a>
|
||||
> *十进制数字* → 数值 0 到 9
|
||||
> *十进制数字* → 数值 0 到 9
|
||||
> <a id="decimal-digits"></a>
|
||||
> *十进制数字组* → [*十进制数字*](#decimal-digit) [*十进制数字组*](#decimal-digits)<sub>可选</sub>
|
||||
> *十进制数字组* → [*十进制数字*](#decimal-digit) [*十进制数字组*](#decimal-digits)<sub>可选</sub>
|
||||
> <a id="decimal-literal-character"></a>
|
||||
> *十进制字符* → [*十进制数字*](#decimal-digit) | _
|
||||
> *十进制字符* → [*十进制数字*](#decimal-digit) | _
|
||||
> <a id="decimal-literal-characters"></a>
|
||||
> *十进制字符组* → [*十进制字符*](#decimal-literal-character) [*十进制字符组*](#decimal-literal-characters)<sub>可选</sub>
|
||||
|
||||
<a id="hexadecimal-literal"></a>
|
||||
> *十六进制字面量* → **0x** [*十六进制数字*](#hexadecimal-digit) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
<a id="hexadecimal-literal"></a>
|
||||
> *十六进制字面量* → **0x** [*十六进制数字*](#hexadecimal-digit) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
> <a id="hexadecimal-digit"></a>
|
||||
> *十六进制数字* → 数值 0 到 9, 字母 a 到 f, 或 A 到 F
|
||||
> *十六进制数字* → 数值 0 到 9, 字母 a 到 f, 或 A 到 F
|
||||
> <a id="hexadecimal-literal-character"></a>
|
||||
> *十六进制字符* → [*十六进制数字*](#hexadecimal-digit) | _
|
||||
> *十六进制字符* → [*十六进制数字*](#hexadecimal-digit) | _
|
||||
> <a id="hexadecimal-literal-characters"></a>
|
||||
> *十六进制字面量字符组* → [*十六进制字符*](#hexadecimal-literal-character) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
> *十六进制字面量字符组* → [*十六进制字符*](#hexadecimal-literal-character) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
|
||||
<a id="floating_point_literals"></a>
|
||||
### 浮点数字面量
|
||||
@ -231,28 +231,28 @@ true // 布尔值字面量
|
||||
|
||||
除非特别指定,浮点数字面量的默认推导类型为 Swift 标准库类型中的 `Double`,表示 64 位浮点数。Swift 标准库也定义了 `Float` 类型,表示 32 位浮点数。
|
||||
|
||||
> 浮点数字面量语法
|
||||
> 浮点数字面量语法
|
||||
>
|
||||
<a id="floating-point-literal"></a>
|
||||
> *浮点数字面量* → [*十进制字面量*](#decimal-literal) [*十进制分数*](#decimal-fraction)<sub>可选</sub> [*十进制指数*](#decimal-exponent)<sub>可选</sub>
|
||||
> *浮点数字面量* → [*十进制字面量*](#decimal-literal) [*十进制分数*](#decimal-fraction)<sub>可选</sub> [*十进制指数*](#decimal-exponent)<sub>可选</sub>
|
||||
> *浮点数字面量* → [*十六进制字面量*](#hexadecimal-literal) [*十六进制分数*](#hexadecimal-fraction)<sub>可选</sub> [*十六进制指数*](#hexadecimal-exponent)
|
||||
|
||||
<a id="decimal-fraction"></a>
|
||||
<a id="decimal-fraction"></a>
|
||||
> *十进制分数* → **.** [*十进制字面量*](#decimal-literal)
|
||||
> <a id="decimal-exponent"></a>
|
||||
> *十进制指数* → [*十进制指数 e*](#floating-point-e) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal-literal)
|
||||
> <a id="decimal-exponent"></a>
|
||||
> *十进制指数* → [*十进制指数 e*](#floating-point-e) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal-literal)
|
||||
|
||||
<a id="hexadecimal-fraction"></a>
|
||||
> *十六进制分数* → **.** [*十六进制数字*](#hexadecimal-digit) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
> *十六进制分数* → **.** [*十六进制数字*](#hexadecimal-digit) [*十六进制字面量字符组*](#hexadecimal-literal-characters)<sub>可选</sub>
|
||||
> <a id="hexadecimal-exponent"></a>
|
||||
> *十六进制指数* → [*十六进制指数 p*](#floating-point-p) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal-literal)
|
||||
> *十六进制指数* → [*十六进制指数 p*](#floating-point-p) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal-literal)
|
||||
|
||||
<a id="floating-point-e"></a>
|
||||
> *十进制指数 e* → **e** | **E**
|
||||
> *十进制指数 e* → **e** | **E**
|
||||
> <a id="floating-point-p"></a>
|
||||
> *十六进制指数 p* → **p** | **P**
|
||||
> *十六进制指数 p* → **p** | **P**
|
||||
> <a id="sign"></a>
|
||||
> *正负号* → **+** | **-**
|
||||
> *正负号* → **+** | **-**
|
||||
|
||||
<a id="string_literals"></a>
|
||||
### 字符串字面量
|
||||
@ -264,9 +264,9 @@ true // 布尔值字面量
|
||||
字符串字面量中不能包含未转义的双引号(`"`)、未转义的反斜线(`\`)、回车符、换行符。
|
||||
|
||||
多行字符串字面量被包在三个双引号中的一串字符组成,形式如下:
|
||||
> """
|
||||
> `字符`
|
||||
> """
|
||||
> """
|
||||
> `字符`
|
||||
> """
|
||||
|
||||
与单行字符串字面量不同的是,多行字符串字面量可以包含不转义的双引号( " ),回车以及换行。它不能包含三个非转义的连续双引号。
|
||||
|
||||
@ -310,29 +310,29 @@ let textA = "Hello " + "world"
|
||||
let textB = "Hello world"
|
||||
```
|
||||
|
||||
> 字符串字面量语法
|
||||
> 字符串字面量语法
|
||||
>
|
||||
<a id="string-literal"></a>
|
||||
> *字符串字面量* → [*静态字符串字面量*](#static-string-literal) | [*插值字符串字面量*](#interpolated-string-literal)
|
||||
|
||||
<a id="static-string-literal"></a>
|
||||
> *静态字符串字面量* → **"**[*引用文本*](#quoted-text)<sub>可选</sub>**"**
|
||||
> *静态字符串字面量* → **"**[*引用文本*](#quoted-text)<sub>可选</sub>**"**
|
||||
> <a id="quoted-text"></a>
|
||||
> *引用文本* → [*引用文本项*](#quoted-text-item) [*引用文本*](#quoted-text)<sub>可选</sub>
|
||||
> <a id="quoted-text-item"></a>
|
||||
> *引用文本项* → [*转义字符*](#escaped-character)
|
||||
> <a id="quoted-text-item"></a>
|
||||
> *引用文本项* → [*转义字符*](#escaped-character)
|
||||
> *引用文本项* → 除了 **"**、**\\**、U+000A、U+000D 以外的所有 Unicode 字符
|
||||
|
||||
<a id="interpolated-string-literal"></a>
|
||||
> *插值字符串字面量* → **"**[*插值文本*](#interpolated-text)<sub>可选</sub>**"**
|
||||
> *插值字符串字面量* → **"**[*插值文本*](#interpolated-text)<sub>可选</sub>**"**
|
||||
> <a id="interpolated-text"></a>
|
||||
> *插值文本* → [*插值文本项*](#interpolated-text-item) [*插值文本*](#interpolated-text)<sub>可选</sub>
|
||||
> <a id="interpolated-text-item"></a>
|
||||
> <a id="interpolated-text-item"></a>
|
||||
> *插值文本项* → **\\****(**[*表达式*](./04_Expressions.html)**)** | [*引用文本项*](#quoted-text-item)
|
||||
|
||||
<a id="escaped-character"></a>
|
||||
> *转义字符* → **\\****0** | **\\****\\** | **\t** | **\n** | **\r** | **\\"** | **\\'**
|
||||
> *转义字符* → **\u {** [*unicode 标量数字*](#unicode-scalar-digits) **}**
|
||||
> *转义字符* → **\\****0** | **\\****\\** | **\t** | **\n** | **\r** | **\\"** | **\\'**
|
||||
> *转义字符* → **\u {** [*unicode 标量数字*](#unicode-scalar-digits) **}**
|
||||
> <a id="unicode-scalar-digits"></a>
|
||||
> *unicode 标量数字* → 一到八位的十六进制数字
|
||||
|
||||
@ -341,14 +341,14 @@ let textB = "Hello world"
|
||||
|
||||
Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基础运算符](../chapter2/02_Basic_Operators.html) 和 [高级运算符](../chapter2/25_Advanced_Operators.html) 中进行了阐述。这一小节将描述哪些字符能用于自定义运算符。
|
||||
|
||||
自定义运算符可以由以下其中之一的 ASCII 字符 `/`、`=`、 `-`、`+`、`!`、`*`、`%`、`<`、`>`、`&`、`|`、`^`、`?` 以及 `~`,或者后面语法中规定的任一个 Unicode 字符(其中包含了*数学运算符*、*零散符号(Miscellaneous Symbols)* 以及印刷符号 (Dingbats) 之类的 Unicode 块)开始。在第一个字符之后,允许使用组合型 Unicode 字符。
|
||||
自定义运算符可以由以下其中之一的 ASCII 字符 `/`、`=`、`-`、`+`、`!`、`*`、`%`、`<`、`>`、`&`、`|`、`^`、`?` 以及 `~`,或者后面语法中规定的任一个 Unicode 字符(其中包含了*数学运算符*、*零散符号(Miscellaneous Symbols)* 以及印刷符号 (Dingbats) 之类的 Unicode 块)开始。在第一个字符之后,允许使用组合型 Unicode 字符。
|
||||
|
||||
您也可以以点号 (`.`) 开头来定义自定义运算符。这些运算符可以包含额外的点,例如 `.+.`。如果某个运算符不是以点号开头的,那么它就无法再包含另外的点号了。例如,`+.+` 就会被看作为一个 `+` 运算符后面跟着一个 `.+` 运算符。
|
||||
|
||||
虽然您可以用问号 `?` 来自定义运算符,但是这个运算符不能只包含单独的一个问号。此外,虽然运算符可以包含一个惊叹号 `!`,但是前缀运算符不能够以问号或者惊叹号开头。
|
||||
|
||||
> 注意
|
||||
>
|
||||
>
|
||||
> 以下这些标记 `=`、`->`、`//`、`/*`、`*/`、`.`、`<`(前缀运算符)、`&`、`?`、`?`(中缀运算符)、`>`(后缀运算符)、`!` 、`?` 是被系统保留的。这些符号不能被重载,也不能用于自定义运算符。
|
||||
|
||||
运算符两侧的空白被用来区分该运算符是否为前缀运算符、后缀运算符或二元运算符。规则总结如下:
|
||||
@ -366,50 +366,50 @@ 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>
|
||||
> *运算符* → [*头部运算符*](#operator-head) [*运算符字符组*](#operator-characters)<sub>可选</sub>
|
||||
> *运算符* → [*头部点运算符*](#dot-operator-head) [*点运算符字符组*](#dot-operator-characters)<sub>可选</sub>
|
||||
|
||||
<a id="operator-head"></a>
|
||||
> *头部运算符* → **/** | **=** | **-** | **+** | **!** | __*__ | **%** | **<** | **>** | **&** | **|** | **^** | **~** | **?**
|
||||
> *头部运算符* → U+00A1–U+00A7
|
||||
> *头部运算符* → U+00A9 或 U+00AB
|
||||
> *头部运算符* → U+00AC 或 U+00AE
|
||||
> *头部运算符* → U+00B0–U+00B1,U+00B6,U+00BB,U+00BF,U+00D7,或 U+00F7
|
||||
> *头部运算符* → U+2016–U+2017 或 U+2020–U+2027
|
||||
> *头部运算符* → U+2030–U+203E
|
||||
> *头部运算符* → U+2041–U+2053
|
||||
> *头部运算符* → U+2055–U+205E
|
||||
> *头部运算符* → U+2190–U+23FF
|
||||
> *头部运算符* → U+2500–U+2775
|
||||
> *头部运算符* → U+2794–U+2BFF
|
||||
> *头部运算符* → U+2E00–U+2E7F
|
||||
> *头部运算符* → U+3001–U+3003
|
||||
<a id="operator-head"></a>
|
||||
> *头部运算符* → **/** | **=** | **-** | **+** | **!** | __*__ | **%** | **<** | **>** | **&** | **|** | **^** | **~** | **?**
|
||||
> *头部运算符* → U+00A1–U+00A7
|
||||
> *头部运算符* → U+00A9 或 U+00AB
|
||||
> *头部运算符* → U+00AC 或 U+00AE
|
||||
> *头部运算符* → U+00B0–U+00B1,U+00B6,U+00BB,U+00BF,U+00D7,或 U+00F7
|
||||
> *头部运算符* → U+2016–U+2017 或 U+2020–U+2027
|
||||
> *头部运算符* → U+2030–U+203E
|
||||
> *头部运算符* → U+2041–U+2053
|
||||
> *头部运算符* → U+2055–U+205E
|
||||
> *头部运算符* → U+2190–U+23FF
|
||||
> *头部运算符* → U+2500–U+2775
|
||||
> *头部运算符* → U+2794–U+2BFF
|
||||
> *头部运算符* → U+2E00–U+2E7F
|
||||
> *头部运算符* → U+3001–U+3003
|
||||
> *头部运算符* → U+3008–U+3030
|
||||
|
||||
<a id="operator-character"></a>
|
||||
> *运算符字符* → [*头部运算符*](#operator-head)
|
||||
> *运算符字符* → U+0300–U+036F
|
||||
> *运算符字符* → U+1DC0–U+1DFF
|
||||
> *运算符字符* → U+20D0–U+20FF
|
||||
> *运算符字符* → U+FE00–U+FE0F
|
||||
> *运算符字符* → U+FE20–U+FE2F
|
||||
> *运算符字符* → U+E0100–U+E01EF
|
||||
<a id="operator-character"></a>
|
||||
> *运算符字符* → [*头部运算符*](#operator-head)
|
||||
> *运算符字符* → U+0300–U+036F
|
||||
> *运算符字符* → U+1DC0–U+1DFF
|
||||
> *运算符字符* → U+20D0–U+20FF
|
||||
> *运算符字符* → U+FE00–U+FE0F
|
||||
> *运算符字符* → U+FE20–U+FE2F
|
||||
> *运算符字符* → U+E0100–U+E01EF
|
||||
> <a id="operator-characters"></a>
|
||||
> *运算符字符组* → [*运算符字符*](#operator-character) [*运算符字符组*](#operator-characters)<sub>可选</sub>
|
||||
> *运算符字符组* → [*运算符字符*](#operator-character) [*运算符字符组*](#operator-characters)<sub>可选</sub>
|
||||
|
||||
<a id="dot-operator-head"></a>
|
||||
> *头部点运算符* → **..**
|
||||
<a id="dot-operator-head"></a>
|
||||
> *头部点运算符* → **..**
|
||||
> <a id="dot-operator-character"></a>
|
||||
> *点运算符字符* → **.** | [*运算符字符*](#operator-character)
|
||||
> *点运算符字符* → **.** | [*运算符字符*](#operator-character)
|
||||
> <a id="dot-operator-characters"></a>
|
||||
> *点运算符字符组* → [*点运算符字符*](#dot-operator-character) [*点运算符字符组*](#dot-operator-characters)<sub>可选</sub>
|
||||
|
||||
<a id="binary-operator"></a>
|
||||
> *二元运算符* → [*运算符*](#operator)
|
||||
> *二元运算符* → [*运算符*](#operator)
|
||||
> <a id="prefix-operator"></a>
|
||||
> *前缀运算符* → [*运算符*](#operator)
|
||||
> *前缀运算符* → [*运算符*](#operator)
|
||||
> <a id="postfix-operator"></a>
|
||||
> *后缀运算符* → [*运算符*](#operator)
|
||||
> *后缀运算符* → [*运算符*](#operator)
|
||||
|
||||
@ -10,9 +10,9 @@
|
||||
|
||||
> 2.1
|
||||
> 翻译:[mmoaay](https://github.com/mmoaay)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
|
||||
@ -33,26 +33,26 @@ Swift 语言存在两种类型:命名型类型和复合型类型。命名型
|
||||
|
||||
那些通常被其它语言认为是基本或原始的数据型类型,比如表示数字、字符和字符串的类型,实际上就是命名型类型,这些类型在 Swift 标准库中是使用结构体来定义和实现的。因为它们是命名型类型,因此你可以按照 [扩展](../chapter2/21_Extensions.html) 和 [扩展声明](05_Declarations.html#extension_declaration) 中讨论的那样,声明一个扩展来增加它们的行为以满足你程序的需求。
|
||||
|
||||
复合型类型是没有名字的类型,它由 Swift 本身定义。Swift 存在两种复合型类型:函数类型和元组类型。一个复合型类型可以包含命名型类型和其它复合型类型。例如,元组类型 `(Int, (Int, 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>
|
||||
@ -68,8 +68,8 @@ func someFunction(a: Int) { /* ... */ }
|
||||
|
||||
类型注解可以在类型之前包含一个类型特性的可选列表。
|
||||
|
||||
> 类型注解语法
|
||||
>
|
||||
> 类型注解语法
|
||||
>
|
||||
<a name="type-annotation"></a>
|
||||
> *类型注解* → **:** [*特性列表*](06_Attributes.html#attributes)<sub>可选</sub> **输入输出参数**<sub>可选</sub> [*类型*](#type)
|
||||
|
||||
@ -93,12 +93,12 @@ 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)
|
||||
> *类型标识符* → [*类型名称*](#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>
|
||||
> *类型名称* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
> *类型名称* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
|
||||
<a name="tuple_type"></a>
|
||||
## 元组类型
|
||||
@ -116,18 +116,18 @@ someTuple = (9, 99) // 正确:命名类型被自动推断
|
||||
someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
||||
```
|
||||
|
||||
所有的元组类型都包含两个及以上元素, 除了`Void`。 `Void` 是空元组类型 `()` 的别名。
|
||||
所有的元组类型都包含两个及以上元素, 除了 `Void`。`Void` 是空元组类型 `()` 的别名。
|
||||
|
||||
> 元组类型语法
|
||||
> 元组类型语法
|
||||
>
|
||||
<a name="tuple-type"></a>
|
||||
> *元组类型* → **(** [*元组类型元素列表*](#tuple-type-element-list) <sub>可选</sub> **)**
|
||||
> *元组类型* → **(** [*元组类型元素列表*](#tuple-type-element-list) <sub>可选</sub> **)**
|
||||
<a name="tuple-type-element-list"></a>
|
||||
> *元组类型元素列表* → [*元组类型元素*](#tuple-type-element) | [*元组类型元素*](#tuple-type-element) **,** [*元组类型元素列表*](#tuple-type-element-list)
|
||||
> *元组类型元素列表* → [*元组类型元素*](#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>
|
||||
> *元素名* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
<a name="element-name"></a>
|
||||
> *元素名* → [*标识符*](02_Lexical_Structure.html#identifier)
|
||||
|
||||
<a name="function_type"></a>
|
||||
## 函数类型
|
||||
@ -138,13 +138,13 @@ someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
||||
|
||||
参数类型是由逗号间隔的类型列表。由于参数类型和返回值类型可以是元组类型,所以函数类型支持多参数与多返回值的函数与方法。
|
||||
|
||||
你可以对函数参数`() - > T `(其中 T 是任何类型)使用 `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)。
|
||||
|
||||
如果一个函数类型只有一个形式参数而且形式参数的类型是元组类型,那么元组类型在写函数类型的时候必须用圆括号括起来。比如说, `((Int, Int)) -> Void` 是接收一个元组 `(Int, Int)` 作为形式参数的函数的类型。与此相反,不加括号的`(Int, Int) -> Void` 是一个接收两个 `Int` 形式参数并且不返回任何值的函数的类型。相似地,因为`Void` 是空元组类型 `()` 的别名, 函数类型`(Void)-> Void`与一个空元组的变量的函数类型`(()) -> ()`是一样的。但这些类型和无变量的函数类型`() -> ()`是不一样的。
|
||||
为了指定一个 `in-out` 参数,可以在参数类型前加 `inout` 前缀。但是你不可以对可变长参数或返回值类型使用 `inout`。关于这种参数的详细讲解请参阅 [输入输出参数](../chapter2/06_Functions.html#in_out_parameters)。
|
||||
|
||||
如果一个函数类型只有一个形式参数而且形式参数的类型是元组类型,那么元组类型在写函数类型的时候必须用圆括号括起来。比如说,`((Int, Int)) -> Void` 是接收一个元组 `(Int, Int)` 作为形式参数的函数的类型。与此相反,不加括号的 `(Int, Int) -> Void` 是一个接收两个 `Int` 形式参数并且不返回任何值的函数的类型。相似地,因为 `Void` 是空元组类型 `()` 的别名, 函数类型 `(Void)-> Void` 与一个空元组的变量的函数类型 `(()) -> ()` 是一样的。但这些类型和无变量的函数类型 `() -> ()` 是不一样的。
|
||||
|
||||
函数和方法中的变量名并不是函数类型的一部分。例如:
|
||||
|
||||
@ -153,7 +153,7 @@ func someFunction(left: Int, right: Int) {}
|
||||
func anotherFunction(left: Int, right: Int) {}
|
||||
func functionWithDifferentLabels(top: Int, bottom: Int) {}
|
||||
|
||||
var f = someFunction // 函数f的类型为 (Int, Int) -> Void, 而不是 (left: Int, right: Int) -> Void.
|
||||
var f = someFunction // 函数 f 的类型为 (Int, Int) -> Void, 而不是 (left: Int, right: Int) -> Void.
|
||||
f = anotherFunction // 正确
|
||||
f = functionWithDifferentLabels // 正确
|
||||
|
||||
@ -163,55 +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 // 正确
|
||||
```
|
||||
|
||||
由于变量标签不是函数类型的一部分,你可以在写函数类型的时候省略它们。
|
||||
|
||||
```
|
||||
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="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)
|
||||
|
||||
@ -241,7 +241,7 @@ 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) **]**
|
||||
@ -268,7 +268,7 @@ let someDictionary: Dictionary<String, Int> = ["Alex": 31, "Paul": 39]
|
||||
|
||||
关于 Swift 标准库中 `Dictionary` 类型的详细讨论,请参阅 [字典](../chapter2/04_Collection_Types.html#dictionaries)。
|
||||
|
||||
> 字典类型语法
|
||||
> 字典类型语法
|
||||
>
|
||||
<a name="dictionary-type"></a>
|
||||
> *字典类型* → **[** [*类型*](#type) **:** [*类型*](#type) **]**
|
||||
@ -300,10 +300,10 @@ optionalInteger! // 42
|
||||
|
||||
更多细节以及更多如何使用可选类型的例子,请参阅 [可选类型](../chapter2/01_The_Basics.html#optionals)。
|
||||
|
||||
> 可选类型语法
|
||||
> 可选类型语法
|
||||
>
|
||||
<a name="optional-type"></a>
|
||||
> *可选类型* → [*类型*](#type) **?**
|
||||
> *可选类型* → [*类型*](#type) **?**
|
||||
|
||||
<a name="implicitly_unwrapped_optional_type"></a>
|
||||
## 隐式解析可选类型
|
||||
@ -327,7 +327,7 @@ let arrayOfImplicitlyUnwrappedElements: [Int!] // 错误
|
||||
let implicitlyUnwrappedArray: [Int]! // 正确
|
||||
```
|
||||
|
||||
由于隐式解析可选类型和可选类型有同样的表达式`Optional<Wrapped>`,你可以在使用可选类型的地方使用隐式解析可选类型。比如,你可以将隐式解析可选类型的值赋给变量、常量和可选属性,反之亦然。
|
||||
由于隐式解析可选类型和可选类型有同样的表达式 `Optional<Wrapped>`,你可以在使用可选类型的地方使用隐式解析可选类型。比如,你可以将隐式解析可选类型的值赋给变量、常量和可选属性,反之亦然。
|
||||
|
||||
正如可选类型一样,你在声明隐式解析可选类型的变量或属性的时候也不用指定初始值,因为它有默认值 `nil`。
|
||||
|
||||
@ -335,10 +335,10 @@ let implicitlyUnwrappedArray: [Int]! // 正确
|
||||
|
||||
关于隐式解析可选类型的更多细节,请参阅 [隐式解析可选类型](../chapter2/01_The_Basics.html#implicityly_unwrapped_optionals)。
|
||||
|
||||
> 隐式解析可选类型语法
|
||||
>
|
||||
> 隐式解析可选类型语法
|
||||
>
|
||||
<a name="implicitly-unwrapped-optional-type"></a>
|
||||
> *隐式解析可选类型* → [*类型*](#type) **!**
|
||||
> *隐式解析可选类型* → [*类型*](#type) **!**
|
||||
|
||||
<a name="protocol_composition_type"></a>
|
||||
## 协议合成类型
|
||||
@ -349,11 +349,11 @@ let implicitlyUnwrappedArray: [Int]! // 正确
|
||||
|
||||
> `Protocol 1` & `Procotol 2`
|
||||
|
||||
协议合成类型允许你指定一个值,其类型符合多个协议的要求且不需要定义一个新的命名型协议来继承它想要符合的各个协议。比如,协议合成类型 `Protocol A & Protocol B & Protocol C` 等效于一个从 `Protocol A`,`Protocol B`, `Protocol C` 继承而来的新协议 `Protocol D`,很显然这样做有效率的多,甚至不需引入一个新名字。
|
||||
协议合成类型允许你指定一个值,其类型符合多个协议的要求且不需要定义一个新的命名型协议来继承它想要符合的各个协议。比如,协议合成类型 `Protocol A & Protocol B & Protocol C` 等效于一个从 `Protocol A`,`Protocol B`,`Protocol C` 继承而来的新协议 `Protocol D`,很显然这样做有效率的多,甚至不需引入一个新名字。
|
||||
|
||||
协议合成列表中的每项必须是协议名或协议合成类型的类型别名。
|
||||
|
||||
> 协议合成类型语法
|
||||
> 协议合成类型语法
|
||||
>
|
||||
<a name="protocol-composition-type"></a>
|
||||
> *协议合成类型* → [*协议标识符*](#protocol-identifier) & [*协议合成延续*](#protocol-composition-continuation)
|
||||
@ -389,7 +389,7 @@ type(of: someInstance).printClassName()
|
||||
// 打印 “SomeSubClass”
|
||||
```
|
||||
|
||||
更多信息可以查看Swift标准库里的`type(of:)`。
|
||||
更多信息可以查看 Swift 标准库里的 `type(of:)`。
|
||||
|
||||
可以使用初始化表达式从某个类型的元类型构造出一个该类型的实例。对于类实例,被调用的构造器必须使用 `required` 关键字标记,或者整个类使用 `final` 关键字标记。
|
||||
|
||||
@ -407,7 +407,7 @@ let metatype: AnotherSubClass.Type = AnotherSubClass.self
|
||||
let anotherInstance = metatype.init(string: "some string")
|
||||
```
|
||||
|
||||
> 元类型语法
|
||||
> 元类型语法
|
||||
>
|
||||
<a name="metatype-type"></a>
|
||||
> *元类型* → [*类型*](#type) **.** **Type** | [*类型*](#type) **.** **Protocol**
|
||||
@ -423,12 +423,12 @@ let anotherInstance = metatype.init(string: "some string")
|
||||
|
||||
枚举定义中的类型继承子句可以是一系列协议,或是枚举的原始值类型的命名型类型。在枚举定义中使用类型继承子句来指定原始值类型的例子,请参阅 [原始值](../chapter2/08_Enumerations.html#raw_values)。
|
||||
|
||||
> 类型继承子句语法
|
||||
>
|
||||
> 类型继承子句语法
|
||||
>
|
||||
<a name="type_inheritance_clause"></a>
|
||||
> *类型继承子句* → **:** [*类型继承列表*](#type-inheritance-list)
|
||||
> *类型继承子句* → **:** [*类型继承列表*](#type-inheritance-list)
|
||||
<a name="type-inheritance-list"></a>
|
||||
> *类型继承列表* → [*类型标识符*](#type-identifier) | [*类型标识符*](#type-identifier) **,** [*类型继承列表*](#type-inheritance-list)
|
||||
> *类型继承列表* → [*类型标识符*](#type-identifier) | [*类型标识符*](#type-identifier) **,** [*类型继承列表*](#type-inheritance-list)
|
||||
<a name="class-requirement"></a>
|
||||
|
||||
|
||||
|
||||
@ -15,9 +15,9 @@
|
||||
> 校对:[175](https://github.com/Brian175)
|
||||
|
||||
> 3.0
|
||||
> 翻译+校对:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
@ -51,12 +51,12 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
|
||||
|
||||
通过前缀表达式和二元表达式可以对简单表达式使用各种运算符。基本表达式从概念上讲是最简单的一种表达式,它是一种访问值的方式。后缀表达式则允许你建立复杂的表达式,例如函数调用和成员访问。每种表达式都在下面有详细论述。
|
||||
|
||||
> 表达式语法
|
||||
>
|
||||
> 表达式语法
|
||||
>
|
||||
<a name="expression"></a>
|
||||
> *表达式* → [*try运算符*](#try-operator)<sub>可选</sub> [*前缀表达式*](#prefix-expression) [*二元表达式列表*](#binary-expressions)<sub>可选</sub>
|
||||
> *表达式* → [*try 运算符*](#try-operator)<sub>可选</sub> [*前缀表达式*](#prefix-expression) [*二元表达式列表*](#binary-expressions)<sub>可选</sub>
|
||||
<a name="expression-list"></a>
|
||||
> *表达式列表* → [*表达式*](#expression) | [*表达式*](#expression) **,** [*表达式列表*](#expression-list)
|
||||
> *表达式列表* → [*表达式*](#expression) | [*表达式*](#expression) **,** [*表达式列表*](#expression-list)
|
||||
|
||||
<a name="prefix_expressions"></a>
|
||||
## 前缀表达式
|
||||
@ -69,13 +69,13 @@ 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)
|
||||
> *前缀表达式* → [*前缀运算符*](02_Lexical_Structure.md#prefix-operator)<sub>可选</sub> [*后缀表达式*](#postfix-expression)
|
||||
> *前缀表达式* → [*输入输出表达式*](#in-out-expression)
|
||||
<a name="in-out-expression"></a>
|
||||
> *输入输出表达式* → **&** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *输入输出表达式* → **&** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="try_operator"></a>
|
||||
### Try 运算符
|
||||
@ -107,8 +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!**
|
||||
|
||||
@ -123,17 +123,17 @@ 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)
|
||||
> *二元表达式* → [*类型转换运算符*](#type-casting-operator)
|
||||
> 二元表达式语法
|
||||
>
|
||||
> *二元表达式* → [*二元运算符*](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)
|
||||
> *二元表达式* → [*类型转换运算符*](#type-casting-operator)
|
||||
<a name="binary-expressions"></a>
|
||||
> *二元表达式列表* → [*二元表达式*](#binary-expression) [*二元表达式列表*](#binary-expressions)<sub>可选</sub>
|
||||
|
||||
@ -153,10 +153,10 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
|
||||
赋值运算符不返回任何值。
|
||||
|
||||
> 赋值运算符语法
|
||||
>
|
||||
> 赋值运算符语法
|
||||
>
|
||||
<a name="assignment-operator"></a>
|
||||
> *赋值运算符* → **=**
|
||||
> *赋值运算符* → **=**
|
||||
|
||||
<a name="ternary_conditional_operator"></a>
|
||||
### 三元条件运算符
|
||||
@ -169,20 +169,23 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction() // 错误:try
|
||||
|
||||
关于使用三元条件运算符的例子,请参阅 [三元条件运算符](../chapter2/02_Basic_Operators.md#ternary_conditional_operator)。
|
||||
|
||||
> 三元条件运算符语法
|
||||
>
|
||||
> 三元条件运算符语法
|
||||
>
|
||||
<a name="conditional-operator"></a>
|
||||
> *三元条件运算符* → **?** [try运算符](#try-operator)<sub>可选</sub> [*表达式*](#expression) **:**
|
||||
> *三元条件运算符* → **?** [try 运算符](#try-operator)<sub>可选</sub> [*表达式*](#expression) **:**
|
||||
|
||||
<a name="type-casting_operators"></a>
|
||||
### 类型转换运算符
|
||||
|
||||
有 4 种类型转换运算符:`is`、`as`、`as? `和`as!`。它们有如下的形式:
|
||||
有 4 种类型转换运算符:`is`、`as`、`as? ` 和 `as!`。它们有如下的形式:
|
||||
|
||||
> `表达式` is `类型`
|
||||
`表达式` as `类型`
|
||||
`表达式` as? `类型`
|
||||
`表达式` as! `类型`
|
||||
> `表达式` is `类型`
|
||||
>
|
||||
> `表达式` as `类型`
|
||||
>
|
||||
> `表达式` as? `类型`
|
||||
>
|
||||
> `表达式` as! `类型`
|
||||
|
||||
`is` 运算符在运行时检查表达式能否向下转化为指定的类型,如果可以则返回 `ture`,否则返回 `false`。
|
||||
|
||||
@ -212,29 +215,29 @@ 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)
|
||||
> *类型转换运算符* → **as** **!** [*类型*](03_Types.md#type)
|
||||
> 类型转换运算符语法
|
||||
>
|
||||
> *类型转换运算符* → **is** [*类型*](03_Types.md#type)
|
||||
> *类型转换运算符* → **as** [*类型*](03_Types.md#type)
|
||||
> *类型转换运算符* → **as** **?** [*类型*](03_Types.md#type)
|
||||
> *类型转换运算符* → **as** **!** [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="primary_expressions"></a>
|
||||
## 基本表达式
|
||||
|
||||
基本表达式是最基本的表达式。它们可以单独使用,也可以跟前缀表达式、二元表达式、后缀表达式组合使用。
|
||||
|
||||
> 基本表达式语法
|
||||
>
|
||||
> 基本表达式语法
|
||||
>
|
||||
<a name="primary-expression"></a>
|
||||
> *基本表达式* → [*标识符*](02_Lexical_Structure.md#identifier) [*泛型实参子句*](08_Generic_Parameters_and_Arguments.md#generic-argument-clause)<sub>可选</sub>
|
||||
> *基本表达式* → [*字面量表达式*](#literal-expression)
|
||||
> *基本表达式* → [*self表达式*](#self-expression)
|
||||
> *基本表达式* → [*超类表达式*](#superclass-expression)
|
||||
> *基本表达式* → [*闭包表达式*](#closure-expression)
|
||||
> *基本表达式* → [*圆括号表达式*](#parenthesized-expression)
|
||||
> *基本表达式* → [*隐式成员表达式*](#implicit-member-expression)
|
||||
> *基本表达式* → [*通配符表达式*](#wildcard-expression)
|
||||
> *基本表达式* → [*标识符*](02_Lexical_Structure.md#identifier) [*泛型实参子句*](08_Generic_Parameters_and_Arguments.md#generic-argument-clause)<sub>可选</sub>
|
||||
> *基本表达式* → [*字面量表达式*](#literal-expression)
|
||||
> *基本表达式* → [*self 表达式*](#self-expression)
|
||||
> *基本表达式* → [*超类表达式*](#superclass-expression)
|
||||
> *基本表达式* → [*闭包表达式*](#closure-expression)
|
||||
> *基本表达式* → [*圆括号表达式*](#parenthesized-expression)
|
||||
> *基本表达式* → [*隐式成员表达式*](#implicit-member-expression)
|
||||
> *基本表达式* → [*通配符表达式*](#wildcard-expression)
|
||||
> *基本表达式* → [*选择器表达式*](#selector-expression)
|
||||
|
||||
<a name="literal_expression"></a>
|
||||
@ -249,7 +252,7 @@ f(x as Any)
|
||||
`#column` | `Int` | 所在的列数
|
||||
`#function` | `String` | 所在的声明的名字
|
||||
|
||||
`#line`除了上述含义外,还有另一种含义。当它出现在单独一行时,会被理解成行控制语句,请参阅[线路控制语句](../chapter3/10_Statements.md#线路控制语句)。
|
||||
`#line` 除了上述含义外,还有另一种含义。当它出现在单独一行时,会被理解成行控制语句,请参阅[线路控制语句](../chapter3/10_Statements.md#线路控制语句)。
|
||||
|
||||
对于 `#function`,在函数中会返回当前函数的名字,在方法中会返回当前方法的名字,在属性的存取器中会返回属性的名字,在特殊的成员如 `init` 或 `subscript` 中会返回这个关键字的名字,在某个文件中会返回当前模块的名字。
|
||||
|
||||
@ -285,36 +288,36 @@ var emptyArray: [Double] = []
|
||||
var emptyDictionary: [String : Double] = [:]
|
||||
```
|
||||
|
||||
> 字面量表达式语法
|
||||
> 字面量表达式语法
|
||||
>
|
||||
<a name="literal-expression"></a>
|
||||
> *字面量表达式* → [*字面量*](02_Lexical_Structure.md#literal)
|
||||
> *字面量表达式* → [*数组字面量*](#array-literal) | [*字典字面量*](#dictionary-literal)
|
||||
> *字面量表达式* → **#file** | **#line** | **#column** | **#function**
|
||||
> *字面量表达式* → [*字面量*](02_Lexical_Structure.md#literal)
|
||||
> *字面量表达式* → [*数组字面量*](#array-literal) | [*字典字面量*](#dictionary-literal)
|
||||
> *字面量表达式* → **#file** | **#line** | **#column** | **#function**
|
||||
|
||||
<a name="array-literal"></a>
|
||||
> *数组字面量* → **[** [*数组字面量项列表*](#array-literal-items)<sub>可选</sub> **]**
|
||||
> *数组字面量* → **[** [*数组字面量项列表*](#array-literal-items)<sub>可选</sub> **]**
|
||||
<a name="array-literal-items"></a>
|
||||
> *数组字面量项列表* → [*数组字面量项*](#array-literal-item) **,**<sub>可选</sub> | [*数组字面量项*](#array-literal-item) **,** [*数组字面量项列表*](#array-literal-items)
|
||||
> *数组字面量项列表* → [*数组字面量项*](#array-literal-item) **,**<sub>可选</sub> | [*数组字面量项*](#array-literal-item) **,** [*数组字面量项列表*](#array-literal-items)
|
||||
<a name="array-literal-item"></a>
|
||||
> *数组字面量项* → [*表达式*](#expression)
|
||||
> *数组字面量项* → [*表达式*](#expression)
|
||||
|
||||
<a name="dictionary-literal"></a>
|
||||
> *字典字面量* → **[** [*字典字面量项列表*](#dictionary-literal-items) **]** | **[** **:** **]**
|
||||
> *字典字面量* → **[** [*字典字面量项列表*](#dictionary-literal-items) **]** | **[** **:** **]**
|
||||
<a name="dictionary-literal-items"></a>
|
||||
> *字典字面量项列表* → [*字典字面量项*](#dictionary-literal-item) **,**<sub>可选</sub> | [*字典字面量项*](#dictionary-literal-item) **,** [*字典字面量项列表*](#dictionary-literal-items)
|
||||
> *字典字面量项列表* → [*字典字面量项*](#dictionary-literal-item) **,**<sub>可选</sub> | [*字典字面量项*](#dictionary-literal-item) **,** [*字典字面量项列表*](#dictionary-literal-items)
|
||||
<a name="dictionary-literal-item"></a>
|
||||
> *字典字面量项* → [*表达式*](#expression) **:** [*表达式*](#expression)
|
||||
> *字典字面量项* → [*表达式*](#expression) **:** [*表达式*](#expression)
|
||||
|
||||
<a name="self_expression"></a>
|
||||
### Self 表达式
|
||||
|
||||
`self` 表达式是对当前类型或者当前实例的显式引用,它有如下形式:
|
||||
|
||||
> self
|
||||
> self.`成员名称`
|
||||
> self[`下标索引`]
|
||||
> self(`构造器参数`)
|
||||
> self
|
||||
> self.`成员名称`
|
||||
> self[`下标索引`]
|
||||
> self(`构造器参数`)
|
||||
> self.init(`构造器参数`)
|
||||
|
||||
如果在构造器、下标、实例方法中,`self` 引用的是当前类型的实例。在一个类型方法中,`self` 引用的是当前的类型。
|
||||
@ -341,42 +344,42 @@ struct Point {
|
||||
}
|
||||
```
|
||||
|
||||
> Self 表达式语法
|
||||
> Self 表达式语法
|
||||
>
|
||||
<a name="self-expression"></a>
|
||||
> *self 表达式* → **self** | [*self 方法表达式*](#self-method-expression) | [*self 下标表达式*](#self-subscript-expression) | [*self 构造器表达式*](#self-initializer-expression)
|
||||
>
|
||||
<a name="self-method-expression"></a>
|
||||
> *self 方法表达式* → **self** **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *self 方法表达式* → **self** **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="self-subscript-expression"></a>
|
||||
> *self 下标表达式* → **self** **[** [*表达式*](#expression) **]**
|
||||
<a name="self-initializer-expression"></a>
|
||||
> *self 构造器表达式* → **self** **.** **init**
|
||||
> *self 构造器表达式* → **self** **.** **init**
|
||||
|
||||
<a name="superclass_expression"></a>
|
||||
### 父类表达式
|
||||
|
||||
*父类*表达式可以使我们在某个类中访问它的超类,它有如下形式:
|
||||
|
||||
> super.`成员名称`
|
||||
> super[`下标索引`]
|
||||
> super.`成员名称`
|
||||
> super[`下标索引`]
|
||||
> super.init(`构造器参数`)
|
||||
|
||||
第一种形式用来访问超类的某个成员,第二种形式用来访问超类的下标,第三种形式用来访问超类的构造器。
|
||||
|
||||
子类可以通过超类表达式在它们的成员、下标和构造器中使用超类中的实现。
|
||||
|
||||
> 父类表达式语法
|
||||
>
|
||||
> 父类表达式语法
|
||||
>
|
||||
<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)
|
||||
> *超类方法表达式* → **super** **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="superclass-subscript-expression"></a>
|
||||
> *超类下标表达式* → **super** **[** [*表达式*](#expression) **]**
|
||||
> *超类下标表达式* → **super** **[** [*表达式*](#expression) **]**
|
||||
<a name="superclass-initializer-expression"></a>
|
||||
> *超类构造器表达式* → **super** **.** **init**
|
||||
> *超类构造器表达式* → **super** **.** **init**
|
||||
|
||||
<a name="closure_expression"></a>
|
||||
### 闭包表达式
|
||||
@ -384,8 +387,8 @@ struct Point {
|
||||
闭包表达式会创建一个闭包,在其他语言中也叫 *lambda* 或*匿名*函数。跟函数一样,闭包包含了待执行的代码,不同的是闭包还会捕获所在环境中的常量和变量。它的形式如下:
|
||||
|
||||
```swift
|
||||
{ (parameters) -> return type in
|
||||
statements
|
||||
{ (parameters) -> return type in
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -415,8 +418,8 @@ myFunction { return $0 + $1 }
|
||||
myFunction { $0 + $1 }
|
||||
```
|
||||
|
||||
关于如何将闭包作为参数来传递的内容,请参阅 [函数调用表达式](#function_call_expression)。
|
||||
|
||||
关于如何将闭包作为参数来传递的内容,请参阅 [函数调用表达式](#function_call_expression)。
|
||||
|
||||
关于逃逸闭包的内容,请参阅[逃逸闭包](./chapter2/07_Closures.md#escaping_closures)
|
||||
|
||||
#### 捕获列表
|
||||
@ -477,26 +480,26 @@ 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) **}**
|
||||
> *闭包表达式* → **{** [*闭包签名*](#closure-signature)<sub>可选</sub> [*语句*](10_Statements.md#statements) **}**
|
||||
|
||||
<a name="closure-signature"></a>
|
||||
> *闭包签名* → [*参数子句*](05_Declarations.md#parameter-clause) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*标识符列表*](02_Lexical_Structure.md#identifier-list) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) [*参数子句*](05_Declarations.md#parameter-clause) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) [*标识符列表*](02_Lexical_Structure.md#identifier-list) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) **in**
|
||||
> *闭包签名* → [*参数子句*](05_Declarations.md#parameter-clause) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*标识符列表*](02_Lexical_Structure.md#identifier-list) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) [*参数子句*](05_Declarations.md#parameter-clause) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) [*标识符列表*](02_Lexical_Structure.md#identifier-list) [*函数结果*](05_Declarations.md#function-result)<sub>可选</sub> **in**
|
||||
> *闭包签名* → [*捕获列表*](#capture-list) **in**
|
||||
|
||||
<a name="capture-list"></a>
|
||||
> *捕获列表* → **[** [*捕获列表项列表*](#capture-list-items) **]**
|
||||
> *捕获列表* → **[** [*捕获列表项列表*](#capture-list-items) **]**
|
||||
<a name="capture-list-items"></a>
|
||||
> *捕获列表项列表* → [*捕获列表项*](#capture-list-item) | [*捕获列表项*](#capture-list-item) **,** [*捕获列表项列表*](#capture-list-items)
|
||||
<a name="capture-list-item"></a>
|
||||
<a name="capture-list-item"></a>
|
||||
> *捕获列表项* → [*捕获说明符*](#capture-specifier)<sub>可选</sub> [*表达式*](#expression)
|
||||
<a name="capture-specifier"></a>
|
||||
> *捕获说明符* → **weak** | **unowned** | **unowned(safe)** | **unowned(unsafe)**
|
||||
<a name="capture-specifier"></a>
|
||||
> *捕获说明符* → **weak** | **unowned** | **unowned(safe)** | **unowned(unsafe)**
|
||||
|
||||
<a name="implicit_member_expression"></a>
|
||||
### 隐式成员表达式
|
||||
@ -512,23 +515,23 @@ var x = MyEnumeration.SomeValue
|
||||
x = .AnotherValue
|
||||
```
|
||||
|
||||
> 隐式成员表达式语法
|
||||
>
|
||||
> 隐式成员表达式语法
|
||||
>
|
||||
<a name="implicit-member-expression"></a>
|
||||
> *隐式成员表达式* → **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *隐式成员表达式* → **.** [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="parenthesized_expression"></a>
|
||||
### 圆括号表达式
|
||||
|
||||
*圆括号表达式*是由圆括号包围的表达式。你可以用圆括号说明成组的表达式的先后操作。成组的圆括号不会改变表达式的类型 - 例如`(1)`的类型就是简单的`Int`。
|
||||
|
||||
> 圆括号表达式语法
|
||||
|
||||
*圆括号表达式*是由圆括号包围的表达式。你可以用圆括号说明成组的表达式的先后操作。成组的圆括号不会改变表达式的类型 - 例如 `(1)` 的类型就是简单的 `Int`。
|
||||
|
||||
> 圆括号表达式语法
|
||||
>
|
||||
<a name="parenthesized-expression"></a>
|
||||
> *圆括号表达式* → **( [*表达式*](#expression) )**
|
||||
|
||||
> *圆括号表达式* → **( [*表达式*](#expression) )**
|
||||
|
||||
<a name="Tuple_Expression"></a>
|
||||
### 元组表达式
|
||||
### 元组表达式
|
||||
|
||||
元组表达式由圆括号和其中多个逗号分隔的子表达式组成。每个子表达式前面可以有一个标识符,用冒号隔开。元组表达式形式如下:
|
||||
|
||||
@ -536,14 +539,14 @@ x = .AnotherValue
|
||||
|
||||
元组表达式可以一个表达式都没有,也可以包含两个或是更多的表达式。单个表达式用括号括起来就是括号表达式了。
|
||||
|
||||
> 元组表达式语法
|
||||
> 元组表达式语法
|
||||
>
|
||||
<a name="tuple-expression"></a>
|
||||
> *元组表达式* → **( )** | **(**[*元组元素*](#tuple-element), [*元组元素列表*](#tuple-element-list) **)**
|
||||
<a name="tuple-element-list"></a>
|
||||
<a name="tuple-element-list"></a>
|
||||
> *元组元素列表* → [*元组元素*](#tuple-element) | [*元组元素*](#tuple-element) **,** [*元组元素列表*](#tuple-element-list)
|
||||
<a name="tuple-element"></a>
|
||||
> *元组元素* → [*表达式*](#expression) | [*标识符*](identifier) **:** [*表达式*](#expression)
|
||||
<a name="tuple-element"></a>
|
||||
> *元组元素* → [*表达式*](#expression) | [*标识符*](identifier) **:** [*表达式*](#expression)
|
||||
|
||||
<a name="wildcard_expression"></a>
|
||||
### 通配符表达式
|
||||
@ -555,15 +558,15 @@ x = .AnotherValue
|
||||
// x 为 10,20 被忽略
|
||||
```
|
||||
|
||||
> 通配符表达式语法
|
||||
>
|
||||
> 通配符表达式语法
|
||||
>
|
||||
<a name="wildcard-expression"></a>
|
||||
> *通配符表达式* → **_**
|
||||
> *通配符表达式* → **_**
|
||||
|
||||
<a name="selector_expression"></a>
|
||||
### 选择器表达式
|
||||
|
||||
选择器表达式可以让你通过选择器来引用在Objective-C中方法(method)和属性(property)的setter和getter方法。
|
||||
选择器表达式可以让你通过选择器来引用在 Objective-C 中方法(method)和属性(property)的 setter 和 getter 方法。
|
||||
|
||||
> \#selector(方法名)
|
||||
\#selector(getter: 属性名)
|
||||
@ -584,9 +587,9 @@ class SomeClass: NSObject {
|
||||
let selectorForMethod = #selector(SomeClass.doSomething(_:))
|
||||
let selectorForPropertyGetter = #selector(getter: SomeClass.property)
|
||||
```
|
||||
当为属性的getter创建选择器时,属性名可以是变量属性或者常量属性的引用。但是当为属性的setter创建选择器时,属性名只可以是对变量属性的引用。
|
||||
当为属性的 getter 创建选择器时,属性名可以是变量属性或者常量属性的引用。但是当为属性的 setter 创建选择器时,属性名只可以是对变量属性的引用。
|
||||
|
||||
方法名称可以包含圆括号来进行分组,并使用as 操作符来区分具有相同方法名但类型不同的方法,例如:
|
||||
方法名称可以包含圆括号来进行分组,并使用 as 操作符来区分具有相同方法名但类型不同的方法,例如:
|
||||
|
||||
```swift
|
||||
extension SomeClass {
|
||||
@ -598,15 +601,16 @@ let anotherSelector = #selector(SomeClass.doSomething(_:) as (SomeClass) -> (Str
|
||||
|
||||
由于选择器是在编译时创建的,因此编译器可以检查方法或者属性是否存在,以及是否在运行时暴露给了 Objective-C 。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 虽然方法名或者属性名是个表达式,但是它不会被求值。
|
||||
|
||||
更多关于如何在 Swift 代码中使用选择器来与 Objective-C API 进行交互的信息,请参阅 [Using Swift with Cocoa and Objective-C (Swift 3)](https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216) 中[Objective-C Selectors](https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID59)部分。
|
||||
|
||||
> 选择器表达式语法
|
||||
> 选择器表达式语法
|
||||
<a name="selector-expression"></a>
|
||||
> *选择器表达式* → __#selector__ **(** [*表达式*](#expression) **)**
|
||||
> *选择器表达式* → __#selector__ **(** [*getter:表达式*](#expression) **)**
|
||||
> *选择器表达式* → __#selector__ **(** [*表达式*](#expression) **)**
|
||||
> *选择器表达式* → __#selector__ **(** [*getter:表达式*](#expression) **)**
|
||||
> *选择器表达式* → __#selector__ **(** [*setter:表达式*](#expression) **)**
|
||||
|
||||
<a name="postfix_expressions"></a>
|
||||
@ -618,17 +622,17 @@ let anotherSelector = #selector(SomeClass.doSomething(_:) as (SomeClass) -> (Str
|
||||
|
||||
关于 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)。
|
||||
|
||||
> 后缀表达式语法
|
||||
> 后缀表达式语法
|
||||
<a name="postfix-expression"></a>
|
||||
> *后缀表达式* → [*基本表达式*](#primary-expression)
|
||||
> *后缀表达式* → [*后缀表达式*](#postfix-expression) [*后缀运算符*](02_Lexical_Structure.md#postfix-operator)
|
||||
> *后缀表达式* → [*函数调用表达式*](#function-call-expression)
|
||||
> *后缀表达式* → [*构造器表达式*](#initializer-expression)
|
||||
> *后缀表达式* → [*显式成员表达式*](#explicit-member-expression)
|
||||
> *后缀表达式* → [*后缀 self 表达式*](#postfix-self-expression)
|
||||
> *后缀表达式* → [*dynamicType 表达式*](#dynamic-type-expression)
|
||||
> *后缀表达式* → [*下标表达式*](#subscript-expression)
|
||||
> *后缀表达式* → [*强制取值表达式*](#forced-value-expression)
|
||||
> *后缀表达式* → [*基本表达式*](#primary-expression)
|
||||
> *后缀表达式* → [*后缀表达式*](#postfix-expression) [*后缀运算符*](02_Lexical_Structure.md#postfix-operator)
|
||||
> *后缀表达式* → [*函数调用表达式*](#function-call-expression)
|
||||
> *后缀表达式* → [*构造器表达式*](#initializer-expression)
|
||||
> *后缀表达式* → [*显式成员表达式*](#explicit-member-expression)
|
||||
> *后缀表达式* → [*后缀 self 表达式*](#postfix-self-expression)
|
||||
> *后缀表达式* → [*dynamicType 表达式*](#dynamic-type-expression)
|
||||
> *后缀表达式* → [*下标表达式*](#subscript-expression)
|
||||
> *后缀表达式* → [*强制取值表达式*](#forced-value-expression)
|
||||
> *后缀表达式* → [*可选链表达式*](#optional-chaining-expression)
|
||||
|
||||
<a name="function_call_expression"></a>
|
||||
@ -660,12 +664,12 @@ myData.someMethod() {$0 == 13}
|
||||
myData.someMethod {$0 == 13}
|
||||
```
|
||||
|
||||
> 函数调用表达式语法
|
||||
> 函数调用表达式语法
|
||||
<a name="function-call-expression"></a>
|
||||
> *函数调用表达式* → [*后缀表达式*](#postfix-expression) [*圆括号表达式*](#parenthesized-expression)
|
||||
> *函数调用表达式* → [*后缀表达式*](#postfix-expression) [*圆括号表达式*](#parenthesized-expression)<sub>可选</sub> [*尾随闭包*](#trailing-closure)
|
||||
> *函数调用表达式* → [*后缀表达式*](#postfix-expression) [*圆括号表达式*](#parenthesized-expression)
|
||||
> *函数调用表达式* → [*后缀表达式*](#postfix-expression) [*圆括号表达式*](#parenthesized-expression)<sub>可选</sub> [*尾随闭包*](#trailing-closure)
|
||||
<a name="trailing-closure"></a>
|
||||
> *尾随闭包* → [*闭包表达式*](#closure-expression)
|
||||
> *尾随闭包* → [*闭包表达式*](#closure-expression)
|
||||
|
||||
<a name="initializer_expression"></a>
|
||||
### 构造器表达式
|
||||
@ -705,9 +709,9 @@ let s4 = someValue.dynamicType(data: 5) // 错误
|
||||
let s3 = someValue.dynamicType.init(data: 7) // 有效
|
||||
```
|
||||
|
||||
> 构造器表达式语法
|
||||
> 构造器表达式语法
|
||||
<a name="initializer-expression"></a>
|
||||
> *构造器表达式* → [*后缀表达式*](#postfix-expression) **.** **init**
|
||||
> *构造器表达式* → [*后缀表达式*](#postfix-expression) **.** **init**
|
||||
> *构造器表达式* → [*后缀表达式*](#postfix-expression) **.** **init** **(** [*参数名称*](#argument-names) **)**
|
||||
|
||||
<a name="explicit_member_expression"></a>
|
||||
@ -765,9 +769,9 @@ let x = [10, 3, 20, 15, 4]
|
||||
.map { $0 * 100 }
|
||||
```
|
||||
|
||||
> 显式成员表达式语法
|
||||
> 显式成员表达式语法
|
||||
<a name="explicit-member-expression"></a>
|
||||
> *显式成员表达式* → [*后缀表达式*](#postfix-expression) **.** [*十进制数字*](02_Lexical_Structure.md#decimal-digit)
|
||||
> *显式成员表达式* → [*后缀表达式*](#postfix-expression) **.** [*十进制数字*](02_Lexical_Structure.md#decimal-digit)
|
||||
> *显式成员表达式* → [*后缀表达式*](#postfix-expression) **.** [*标识符*](02_Lexical_Structure.md#identifier) [*泛型实参子句*](08_Generic_Parameters_and_Arguments.md#generic-argument-clause)<sub>可选</sub><br/>
|
||||
> *显式成员表达式* → [*后缀表达式*](#postfix-expression) **.** [*标识符*](02_Lexical_Structure.md#identifier) **(** [*参数名称*](#argument-names) **)**
|
||||
>
|
||||
@ -781,16 +785,16 @@ let x = [10, 3, 20, 15, 4]
|
||||
|
||||
后缀 `self` 表达式由某个表达式或类型名紧跟 `.self` 组成,其形式如下:
|
||||
|
||||
> `表达式`.self
|
||||
> `类型`.self
|
||||
> `表达式`.self
|
||||
> `类型`.self
|
||||
|
||||
第一种形式返回表达式的值。例如:`x.self` 返回 `x`。
|
||||
|
||||
第二种形式返回相应的类型。我们可以用它来获取某个实例的类型作为一个值来使用。例如,`SomeClass.self` 会返回 `SomeClass` 类型本身,你可以将其传递给相应函数或者方法作为参数。
|
||||
|
||||
> 后缀 self 表达式语法
|
||||
> 后缀 self 表达式语法
|
||||
<a name="postfix-self-expression"></a>
|
||||
> *后缀 self 表达式* → [*后缀表达式*](#postfix-expression) **.** **self**
|
||||
> *后缀 self 表达式* → [*后缀表达式*](#postfix-expression) **.** **self**
|
||||
|
||||
<a name="dynamic_type_expression"></a>
|
||||
### dynamicType 表达式
|
||||
@ -819,9 +823,9 @@ type(of: someInstance).printClassName()
|
||||
// 打印 “SomeSubClass”
|
||||
```
|
||||
|
||||
> 动态类型表达式语法
|
||||
> 动态类型表达式语法
|
||||
<a name="dynamic-type-expression"></a>
|
||||
> *动态类型表达式* → type(of:表达式) **.** **dynamicType**
|
||||
> *动态类型表达式* → type(of:表达式) **.** **dynamicType**
|
||||
|
||||
<a name="subscript_expression"></a>
|
||||
### 下标表达式
|
||||
@ -834,9 +838,9 @@ type(of: someInstance).printClassName()
|
||||
|
||||
关于下标的声明,请参阅 [协议下标声明](05_Declarations.md#protocol_subscript_declaration)。
|
||||
|
||||
> 下标表达式语法
|
||||
> 下标表达式语法
|
||||
<a name="subscript-expression"></a>
|
||||
> *下标表达式* → [*后缀表达式*](#postfix-expression) **[** [*表达式列表*](#expression-list) **]**
|
||||
> *下标表达式* → [*后缀表达式*](#postfix-expression) **[** [*表达式列表*](#expression-list) **]**
|
||||
|
||||
<a name="forced-Value_expression"></a>
|
||||
### 强制取值表达式
|
||||
@ -859,9 +863,9 @@ someDictionary["a"]![0] = 100
|
||||
// someDictionary 现在是 [b: [10, 20], a: [100, 2, 3]]
|
||||
```
|
||||
|
||||
> 强制取值语法
|
||||
> 强制取值语法
|
||||
<a name="forced-value-expression"></a>
|
||||
> *强制取值表达式* → [*后缀表达式*](#postfix-expression) **!**
|
||||
> *强制取值表达式* → [*后缀表达式*](#postfix-expression) **!**
|
||||
|
||||
<a name="optional-chaining_expression"></a>
|
||||
### 可选链表达式
|
||||
@ -909,6 +913,6 @@ someDictionary["a"]?[0] = someFunctionWithSideEffects()
|
||||
// someDictionary 现在是 ["b": [10, 20], "a": [42, 2, 3]]
|
||||
```
|
||||
|
||||
> 可选链表达式语法
|
||||
> 可选链表达式语法
|
||||
<a name="optional-chaining-expression"></a>
|
||||
> *可选链表达式* → [*后缀表达式*](#postfix-expression) **?**
|
||||
> *可选链表达式* → [*后缀表达式*](#postfix-expression) **?**
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
> 翻译:[chenmingbiao](https://github.com/chenmingbiao)
|
||||
|
||||
> 3.0
|
||||
> 翻译:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译:[chenmingjia](https://github.com/chenmingjia)
|
||||
|
||||
> 4.1
|
||||
> 翻译+校对:[mylittleswift](https://github.com/mylittleswift)
|
||||
|
||||
本页包含内容:
|
||||
@ -48,19 +48,19 @@
|
||||
|
||||
是否将分号(`;`)添加到语句的末尾是可选的。但若要在同一行内写多条独立语句,则必须使用分号。
|
||||
|
||||
> 语句语法
|
||||
> 语句语法
|
||||
<a name="statement"></a>
|
||||
> *语句* → [*表达式*](04_Expressions.md#expression) **;**<sub>可选</sub>
|
||||
> *语句* → [*声明*](05_Declarations.md#declaration) **;**<sub>可选</sub>
|
||||
> *语句* → [*循环语句*](#loop-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*分支语句*](#branch-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*带标签的语句*](#labeled-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*控制转移语句*](#control-transfer-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*defer 语句*](#defer-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*do 语句*](#do-statement) **:**<sub>可选</sub>
|
||||
> *语句* → [*编译器控制语句*](#compiler-control-statement)
|
||||
> *语句* → [*表达式*](04_Expressions.md#expression) **;**<sub>可选</sub>
|
||||
> *语句* → [*声明*](05_Declarations.md#declaration) **;**<sub>可选</sub>
|
||||
> *语句* → [*循环语句*](#loop-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*分支语句*](#branch-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*带标签的语句*](#labeled-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*控制转移语句*](#control-transfer-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*defer 语句*](#defer-statement) **;**<sub>可选</sub>
|
||||
> *语句* → [*do 语句*](#do-statement) **:**<sub>可选</sub>
|
||||
> *语句* → [*编译器控制语句*](#compiler-control-statement)
|
||||
<a name="statements"></a>
|
||||
> *多条语句* → [*语句*](#statement) [*多条语句*](#statements)<sub>可选</sub>
|
||||
> *多条语句* → [*语句*](#statement) [*多条语句*](#statements)<sub>可选</sub>
|
||||
|
||||
<a name="loop_statements"></a>
|
||||
## 循环语句
|
||||
@ -69,11 +69,11 @@
|
||||
|
||||
通过 `break` 语句和 `continue` 语句可以改变循环语句的控制流。有关这两条语句,详情参见 [Break 语句](#break_statement) 和 [Continue 语句](#continue_statement)。
|
||||
|
||||
> 循环语句语法
|
||||
> 循环语句语法
|
||||
<a name="loop-statement"></a>
|
||||
> *循环语句* → [*for-in 语句*](#for-in-statement)
|
||||
> *循环语句* → [*while 语句*](#while-statement)
|
||||
> *循环语句* → [*repeat-while 语句*](#repeat-while-statement)
|
||||
> *循环语句* → [*for-in 语句*](#for-in-statement)
|
||||
> *循环语句* → [*while 语句*](#while-statement)
|
||||
> *循环语句* → [*repeat-while 语句*](#repeat-while-statement)
|
||||
|
||||
<a name="for-in_statements"></a>
|
||||
### For-In 语句
|
||||
@ -83,17 +83,17 @@
|
||||
`for-in` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
for item in collection {
|
||||
statements
|
||||
}
|
||||
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)
|
||||
> *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)
|
||||
|
||||
<a name="while_statements"></a>
|
||||
### While 语句
|
||||
@ -103,9 +103,9 @@ for item in collection {
|
||||
`while` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
while condition {
|
||||
while condition {
|
||||
statements
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`while` 语句的执行流程如下:
|
||||
@ -115,21 +115,21 @@ while condition {
|
||||
|
||||
由于会在执行循环体中的语句前判断条件的值,因此循环体中的语句可能会被执行若干次,也可能一次也不会被执行。
|
||||
|
||||
条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
|
||||
条件的结果必须是 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)
|
||||
> *while 语句* → **while** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
<a name="condition-clause"></a>
|
||||
> *条件子句* → [*表达式*](04_Expressions.md#expression) | [*表达式*](04_Expressions.md#expression) **,** [*条件列表*](#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)
|
||||
> *条件* → [*表达式*](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)
|
||||
> *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)
|
||||
> *可选绑定条件* → **let** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer) | **var** [*模式*](07_Patterns.md#pattern) [*构造器*](05_Declarations.md#initializer)
|
||||
|
||||
<a name="repeat-while_statements"></a>
|
||||
### Repeat-While 语句
|
||||
@ -139,8 +139,8 @@ while condition {
|
||||
`repeat-while` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
repeat {
|
||||
statements
|
||||
repeat {
|
||||
statements
|
||||
} while condition
|
||||
```
|
||||
|
||||
@ -151,12 +151,12 @@ repeat {
|
||||
|
||||
由于条件的值是在循环体中的语句执行后才进行判断,因此循环体中的语句至少会被执行一次。
|
||||
|
||||
条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件语句也可以使用可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.md#optional_binding)。
|
||||
条件的结果必须是 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)
|
||||
> *repeat-while 语句* → **repeat** [*代码块*](05_Declarations.md#code-block) **while** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="branch_statements"></a>
|
||||
## 分支语句
|
||||
@ -165,12 +165,12 @@ repeat {
|
||||
|
||||
`if` 语句和 `switch` 语句中的控制流可以用 `break` 语句改变,请参阅 [Break 语句](#break_statement)。
|
||||
|
||||
> 分支语句语法
|
||||
> 分支语句语法
|
||||
>
|
||||
<a name="branch-statement"></a>
|
||||
> *分支语句* → [*if 语句*](#if-statement)
|
||||
> *分支语句* → [*guard 语句*](#guard-statement)
|
||||
> *分支语句* → [*switch 语句*](#switch-statement)
|
||||
> *分支语句* → [*if 语句*](#if-statement)
|
||||
> *分支语句* → [*guard 语句*](#guard-statement)
|
||||
> *分支语句* → [*switch 语句*](#switch-statement)
|
||||
|
||||
<a name="if_statements"></a>
|
||||
### If 语句
|
||||
@ -182,17 +182,17 @@ repeat {
|
||||
第一种形式是当且仅当条件为真时执行代码,像下面这样:
|
||||
|
||||
```swift
|
||||
if condition {
|
||||
statements
|
||||
}
|
||||
if condition {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
第二种形式是在第一种形式的基础上添加 `else` 语句,当只有一个 `else` 语句时,像下面这样:
|
||||
|
||||
```swift
|
||||
if ondition {
|
||||
statements to execute if condition is true
|
||||
} else {
|
||||
if ondition {
|
||||
statements to execute if condition is true
|
||||
} else {
|
||||
statements to execute if condition is false
|
||||
}
|
||||
```
|
||||
@ -200,52 +200,52 @@ if ondition {
|
||||
`else` 语句也可包含 `if` 语句,从而形成一条链来测试更多的条件,像下面这样:
|
||||
|
||||
```swift
|
||||
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 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` 语句中条件的结果必须是 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>
|
||||
> *if 语句* → **if** [*条件子句*](#condition-clause) [*代码块*](05_Declarations.md#code-block) [*else 子句*](#else-clause)<sub>可选</sub>
|
||||
<a name="else-clause"></a>
|
||||
> *else 子句* → **else** [*代码块*](05_Declarations.md#code-block) | **else** [*if语句*](#if-statement)
|
||||
> *else 子句* → **else** [*代码块*](05_Declarations.md#code-block) | **else** [*if 语句*](#if-statement)
|
||||
|
||||
<a name="guard_statements"></a>
|
||||
### Guard 语句
|
||||
### Guard 语句
|
||||
|
||||
如果一个或者多个条件不成立,可用 `guard` 语句用来退出当前作用域。
|
||||
|
||||
`guard` 语句的格式如下:
|
||||
|
||||
```swift
|
||||
guard condition else {
|
||||
guard condition else {
|
||||
statements
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`guard` 语句中条件的结果必须是Bool类型或者Bool的桥接类型。另外,条件也可以是一条可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
|
||||
`guard` 语句中条件的结果必须是 Bool 类型或者 Bool 的桥接类型。另外,条件也可以是一条可选绑定,请参阅 [可选绑定](../chapter2/01_The_Basics.html#optional_binding)。
|
||||
|
||||
在 `guard` 语句中进行可选绑定的常量或者变量,其可用范围从声明开始直到作用域结束。
|
||||
|
||||
`guard` 语句必须有 `else` 子句,而且必须在该子句中调用 `Never` 返回类型的函数,或者使用下面的语句退出当前作用域:
|
||||
`guard` 语句必须有 `else` 子句,而且必须在该子句中调用 `Never` 返回类型的函数,或者使用下面的语句退出当前作用域:
|
||||
|
||||
* `return`
|
||||
* `break`
|
||||
* `continue`
|
||||
* `throw`
|
||||
* `throw`
|
||||
|
||||
关于控制转移语句,请参阅 [控制转移语句](#control_transfer_statements)。关于`Never`返回类型的函数,请参阅 [永不返回的函数](05_Declarations.md#rethrowing_functions_and_methods)。
|
||||
关于控制转移语句,请参阅 [控制转移语句](#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)
|
||||
|
||||
@ -257,16 +257,16 @@ guard condition else {
|
||||
`switch` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
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 control expression {
|
||||
case pattern 1:
|
||||
statements
|
||||
case pattern 2 where condition:
|
||||
statements
|
||||
case pattern 3 where condition,
|
||||
pattern 4 where condition:
|
||||
statements
|
||||
default:
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
@ -294,26 +294,26 @@ 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> **}**
|
||||
> *switch 语句* → **switch** [*表达式*](04_Expressions.md#expression) **{** [*switch-case 列表*](#switch-cases)<sub>可选</sub> **}**
|
||||
<a name="switch-cases"></a>
|
||||
> *switch case 列表* → [*switch-case*](#switch-case) [*switch-case列表*](#switch-cases)<sub>可选</sub>
|
||||
> *switch case 列表* → [*switch-case*](#switch-case) [*switch-case 列表*](#switch-cases)<sub>可选</sub>
|
||||
<a name="switch-case"></a>
|
||||
> *switch case* → [*case标签*](#case-label) [*多条语句*](#statements) | [*default标签*](#default-label) [*多条语句*](#statements)
|
||||
> *switch case* → [*case 标签*](#case-label) [*多条语句*](#statements) | [*default 标签*](#default-label) [*多条语句*](#statements)
|
||||
|
||||
<a name="case-label"></a>
|
||||
> *case 标签* → **case** [*case项列表*](#case-item-list) **:**
|
||||
> *case 标签* → **case** [*case 项列表*](#case-item-list) **:**
|
||||
<a name="case-item-list"></a>
|
||||
> *case 项列表* → [*模式*](07_Patterns.md#pattern) [*where子句*](#where-clause)<sub>可选</sub> | [*模式*](07_Patterns.md#pattern) [*where子句*](#where-clause)<sub>可选</sub> **,** [*case项列表*](#case-item-list)
|
||||
> *case 项列表* → [*模式*](07_Patterns.md#pattern) [*where 子句*](#where-clause)<sub>可选</sub> | [*模式*](07_Patterns.md#pattern) [*where 子句*](#where-clause)<sub>可选</sub> **,** [*case 项列表*](#case-item-list)
|
||||
<a name="default-label"></a>
|
||||
> *default 标签* → **default** **:**
|
||||
> *default 标签* → **default** **:**
|
||||
|
||||
<a name="where-clause"></a>
|
||||
> *where-clause* → **where** [*where表达式*](#where-expression)
|
||||
> *where-clause* → **where** [*where 表达式*](#where-expression)
|
||||
<a name="where-expression"></a>
|
||||
> *where-expression* → [*表达式*](04_Expressions.md#expression)
|
||||
> *where-expression* → [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="labeled_statements"></a>
|
||||
## 带标签的语句
|
||||
@ -324,35 +324,35 @@ 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)
|
||||
> *带标签的语句* → [*语句标签*](#statement-label) [*循环语句*](#loop-statement) | [*语句标签*](#statement-label) [*if 语句*](#if-statement) | [*语句标签*](#statement-label) [*switch 语句*](#switch-statement)
|
||||
<a name="statement-label"></a>
|
||||
> *语句标签* → [*标签名称*](#label-name) **:**
|
||||
> *语句标签* → [*标签名称*](#label-name) **:**
|
||||
<a name="label-name"></a>
|
||||
> *标签名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *标签名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="control_transfer_statements"></a>
|
||||
## 控制转移语句
|
||||
|
||||
控制转移语句能够无条件地把控制权从一片代码转移到另一片代码,从而改变代码执行的顺序。Swift 提供五种类型的控制转移语句:`break` 语句、`continue` 语句、`fallthrough` 语句、`return` 语句和 `throw` 语句。
|
||||
|
||||
> 控制转移语句语法
|
||||
> 控制转移语句语法
|
||||
>
|
||||
<a name="control-transfer-statement"></a>
|
||||
> *控制转移语句* → [*break 语句*](#break-statement)
|
||||
> *控制转移语句* → [*continue 语句*](#continue-statement)
|
||||
> *控制转移语句* → [*fallthrough 语句*](#fallthrough-statement)
|
||||
> *控制转移语句* → [*return 语句*](#return-statement)
|
||||
> *控制转移语句* → [*throw 语句*](#throw-statement)
|
||||
> *控制转移语句* → [*break 语句*](#break-statement)
|
||||
> *控制转移语句* → [*continue 语句*](#continue-statement)
|
||||
> *控制转移语句* → [*fallthrough 语句*](#fallthrough-statement)
|
||||
> *控制转移语句* → [*return 语句*](#return-statement)
|
||||
> *控制转移语句* → [*throw 语句*](#throw-statement)
|
||||
|
||||
<a name="break_statement"></a>
|
||||
### Break 语句
|
||||
|
||||
`break` 语句用于终止循环语句、`if` 语句或 `switch` 语句的执行。使用 `break` 语句时,可以只写 `break` 这个关键词,也可以在 `break` 后面跟上标签名,像下面这样:
|
||||
|
||||
> break
|
||||
> break
|
||||
> break `label name`
|
||||
|
||||
当 `break` 语句后面带标签名时,可用于终止由这个标签标记的循环语句、`if` 语句或 `switch` 语句的执行。
|
||||
@ -363,8 +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>
|
||||
|
||||
@ -373,8 +373,8 @@ case let (x, y) where x == y:
|
||||
|
||||
`continue` 语句用于终止循环中当前迭代的执行,但不会终止该循环的执行。使用 `continue` 语句时,可以只写 `continue` 这个关键词,也可以在 `continue` 后面跟上标签名,像下面这样:
|
||||
|
||||
> continue
|
||||
> continue `label name`
|
||||
> continue
|
||||
> continue `label name`
|
||||
|
||||
当 `continue` 语句后面带标签名时,可用于终止由这个标签标记的循环中当前迭代的执行。
|
||||
|
||||
@ -386,8 +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>
|
||||
|
||||
@ -400,10 +400,10 @@ 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**
|
||||
> *fallthrough 语句* → **fallthrough**
|
||||
|
||||
<a name="return_statements"></a>
|
||||
### Return 语句
|
||||
@ -412,46 +412,46 @@ case let (x, y) where x == y:
|
||||
|
||||
使用 `return` 语句时,可以只写 `return` 这个关键词,也可以在 `return` 后面跟上表达式,像下面这样:
|
||||
|
||||
> return
|
||||
> return `expression`
|
||||
> 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>
|
||||
|
||||
<a name="throw_statements"></a>
|
||||
### Throw 语句
|
||||
### Throw 语句
|
||||
|
||||
`throw` 语句出现在抛出函数或者抛出方法体内,或者类型被 `throws` 关键字标记的闭包表达式体内。
|
||||
`throw` 语句出现在抛出函数或者抛出方法体内,或者类型被 `throws` 关键字标记的闭包表达式体内。
|
||||
|
||||
`throw` 语句使程序在当前作用域结束执行,并向外围作用域传播错误。抛出的错误会一直传递,直到被 `do` 语句的 `catch` 子句处理掉。
|
||||
`throw` 语句使程序在当前作用域结束执行,并向外围作用域传播错误。抛出的错误会一直传递,直到被 `do` 语句的 `catch` 子句处理掉。
|
||||
|
||||
`throw` 语句由 `throw` 关键字紧跟一个表达式组成,如下所示:
|
||||
|
||||
> throw `expression`
|
||||
> throw `expression`
|
||||
|
||||
表达式的结果必须符合 `ErrorType` 协议。
|
||||
|
||||
关于如何使用 `throw` 语句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md) 一章的 [用 throwing 函数传递错误](../chapter2/18_Error_Handling.md#propagating_errors_using_throwing_functions)。
|
||||
关于如何使用 `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)
|
||||
|
||||
<a name="defer_statements"></a>
|
||||
## Defer 语句
|
||||
|
||||
`defer` 语句用于在退出当前作用域之前执行代码。
|
||||
`defer` 语句用于在退出当前作用域之前执行代码。
|
||||
|
||||
`defer` 语句形式如下:
|
||||
|
||||
@ -461,9 +461,9 @@ defer {
|
||||
}
|
||||
```
|
||||
|
||||
在 `defer` 语句中的语句无论程序控制如何转移都会被执行。在某些情况下,例如,手动管理资源时,比如关闭文件描述符,或者即使抛出了错误也需要执行一些操作时,就可以使用 `defer` 语句。
|
||||
在 `defer` 语句中的语句无论程序控制如何转移都会被执行。在某些情况下,例如,手动管理资源时,比如关闭文件描述符,或者即使抛出了错误也需要执行一些操作时,就可以使用 `defer` 语句。
|
||||
|
||||
如果多个 `defer` 语句出现在同一作用域内,那么它们执行的顺序与出现的顺序相反。给定作用域中的第一个 `defer` 语句,会在最后执行,这意味着代码中最靠后的 `defer` 语句中引用的资源可以被其他 `defer` 语句清理掉。
|
||||
如果多个 `defer` 语句出现在同一作用域内,那么它们执行的顺序与出现的顺序相反。给定作用域中的第一个 `defer` 语句,会在最后执行,这意味着代码中最靠后的 `defer` 语句中引用的资源可以被其他 `defer` 语句清理掉。
|
||||
|
||||
```swift
|
||||
func f() {
|
||||
@ -479,55 +479,55 @@ f()
|
||||
|
||||
`defer` 语句中的语句无法将控制权转移到 `defer` 语句外部。
|
||||
|
||||
> defer 语句语法
|
||||
>
|
||||
> defer 语句语法
|
||||
>
|
||||
<a name="defer-statement"></a>
|
||||
> *延迟语句* → **defer** [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
<a name="do_statements"></a>
|
||||
## Do 语句
|
||||
|
||||
`do` 语句用于引入一个新的作用域,该作用域中可以含有一个或多个 `catch` 子句,`catch` 子句中定义了一些匹配错误条件的模式。`do` 语句作用域内定义的常量和变量只能在 `do` 语句作用域内使用。
|
||||
`do` 语句用于引入一个新的作用域,该作用域中可以含有一个或多个 `catch` 子句,`catch` 子句中定义了一些匹配错误条件的模式。`do` 语句作用域内定义的常量和变量只能在 `do` 语句作用域内使用。
|
||||
|
||||
Swift 中的 `do` 语句与 C 中限定代码块界限的大括号(`{}`)很相似,也并不会降低程序运行时的性能。
|
||||
Swift 中的 `do` 语句与 C 中限定代码块界限的大括号(`{}`)很相似,也并不会降低程序运行时的性能。
|
||||
|
||||
`do` 语句的形式如下:
|
||||
|
||||
```swift
|
||||
do {
|
||||
try expression
|
||||
statements
|
||||
} catch pattern 1 {
|
||||
statements
|
||||
} catch pattern 2 where condition {
|
||||
statements
|
||||
do {
|
||||
try expression
|
||||
statements
|
||||
} catch pattern 1 {
|
||||
statements
|
||||
} catch pattern 2 where condition {
|
||||
statements
|
||||
}
|
||||
```
|
||||
|
||||
如同 `switch` 语句,编译器会判断 `catch` 子句是否有遗漏。如果 `catch` 子句没有遗漏,则认为错误已被处理。否则,错误会自动传递到外围作用域,被某个 `catch` 子句处理掉或者被用 `throws` 关键字声明的抛出函数继续向外抛出。
|
||||
如同 `switch` 语句,编译器会判断 `catch` 子句是否有遗漏。如果 `catch` 子句没有遗漏,则认为错误已被处理。否则,错误会自动传递到外围作用域,被某个 `catch` 子句处理掉或者被用 `throws` 关键字声明的抛出函数继续向外抛出。
|
||||
|
||||
为了确保错误已经被处理,可以让 `catch` 子句使用匹配所有错误的模式,如通配符模式(`_`)。如果一个 `catch` 子句不指定一种具体模式,`catch` 子句会匹配任何错误,并绑定到名为 `error` 的局部常量。有关在 `catch` 子句中使用模式的更多信息,请参阅 [模式](07_Patterns.md)。
|
||||
|
||||
关于如何在 `do` 语句中使用一系列 `catch` 子句的例子,请参阅 [错误处理](../chapter2/18_Error_Handling.md#handling_errors)。
|
||||
关于如何在 `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>
|
||||
> *do 语句* → **do** [*代码块*](05_Declarations.md#code-block) [*多条 catch 子句*](#catch-clauses)<sub>可选</sub>
|
||||
<a name="catch-clauses"></a>
|
||||
> *多条 catch 子句* → [*catch子句*](#catch-clause) [*多条 catch子句*](#catch-clauses)<sub>可选</sub>
|
||||
> *多条 catch 子句* → [*catch 子句*](#catch-clause) [*多条 catch 子句*](#catch-clauses)<sub>可选</sub>
|
||||
<a name="catch-clause"></a>
|
||||
> *catch 子句* → **catch** [*模式*](07_Patterns.md#pattern)<sub>可选</sub> [*where子句*](#where-clause)<sub>可选</sub> [*代码块*](05_Declarations.md#code-block)
|
||||
> *catch 子句* → **catch** [*模式*](07_Patterns.md#pattern)<sub>可选</sub> [*where 子句*](#where-clause)<sub>可选</sub> [*代码块*](05_Declarations.md#code-block)
|
||||
|
||||
<a name="compiler_control_statements"></a>
|
||||
## 编译器控制语句
|
||||
|
||||
编译器控制语句允许程序改变编译器的行为。Swift 有两种编译器控制语句:编译配置语句和线路控制语句。
|
||||
|
||||
> 编译器控制语句语法
|
||||
>
|
||||
> 编译器控制语句语法
|
||||
>
|
||||
<a name="compiler-control-statement"></a>
|
||||
> *编译器控制语句* → [*编译配置语句*](#build-config-statement)
|
||||
> *编译器控制语句* → [*编译配置语句*](#build-config-statement)
|
||||
> *编译器控制语句* → [*线路控制语句*](#line-control-statement)
|
||||
|
||||
<a name="build_config_statements"></a>
|
||||
@ -538,8 +538,8 @@ do {
|
||||
每一个编译配置语句都以 `#if` 开始,`#endif` 结束。如下是一个简单的编译配置语句:
|
||||
|
||||
```swift
|
||||
#if compilation condition
|
||||
statements
|
||||
#if compilation condition
|
||||
statements
|
||||
#endif
|
||||
```
|
||||
|
||||
@ -555,7 +555,7 @@ statements
|
||||
|
||||
`swift()`(语言版本检测函数)的版本号参数主要由主版本号和次版本号组成并且使用点号(`.`)分隔开,`>=` 和版本号之间不能有空格。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> `arch(arm)` 平台检测函数在 ARM 64 位设备上不会返回 `true`。如果代码在 32 位的 iOS 模拟器上编译,`arch(i386)` 平台检测函数会返回 `true`。
|
||||
|
||||
@ -564,50 +564,50 @@ statements
|
||||
就像 `if` 语句一样,你可以使用 `#elseif` 子句来添加任意多个条件分支来测试不同的编译配置。你也可以使用 `#else` 子句来添加最终的条件分支。包含多个分支的编译配置语句例子如下:
|
||||
|
||||
```swift
|
||||
#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
|
||||
#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**
|
||||
> *单个编译配置语句* → **#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>
|
||||
> *多个编译配置 elseif 子句* → [*单个编译配置elseif子句*](#build-configuration-elseif-clause) [*多个编译配置elseif子句*](build-configuration-elseif-clauses)<sub>可选</sub>
|
||||
> *多个编译配置 elseif 子句* → [*单个编译配置 elseif 子句*](#build-configuration-elseif-clause) [*多个编译配置 elseif 子句*](build-configuration-elseif-clauses)<sub>可选</sub>
|
||||
<a name="build-configuration-elseif-clause"></a>
|
||||
> *单个编译配置 elseif 子句* → **#elseif** [*编译配置*](#build-configuration) [*语句*](#statements)<sub>可选</sub>
|
||||
> *单个编译配置 elseif 子句* → **#elseif** [*编译配置*](#build-configuration) [*语句*](#statements)<sub>可选</sub>
|
||||
<a name="build-configuration-else-clause"></a>
|
||||
> *单个编译配置 else 子句* → **#else** [*语句*](#statements)<sub>可选</sub>
|
||||
|
||||
<a name="build-configuration"></a>
|
||||
> *编译配置* → [*平台检测函数*](#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)
|
||||
> *编译配置* → [*平台检测函数*](#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)
|
||||
|
||||
<a name="platform-testing-function"></a>
|
||||
> *平台检测函数* → **os** **(** [*操作系统*](#operating-system) **)**
|
||||
> *平台检测函数* → **arch** **(** [*架构*](#architecture) **)**
|
||||
> *平台检测函数* → **os** **(** [*操作系统*](#operating-system) **)**
|
||||
> *平台检测函数* → **arch** **(** [*架构*](#architecture) **)**
|
||||
<a name="language-version-testing-function"></a>
|
||||
> *语言版本检测函数* → **swift** **(** **>=** [*swift版本*](#swift-version) **)**
|
||||
> *语言版本检测函数* → **swift** **(** **>=** [*swift 版本*](#swift-version) **)**
|
||||
<a name="operating-system"></a>
|
||||
> *操作系统* → **OSX** | **iOS** | **watchOS** | **tvOS**
|
||||
> *操作系统* → **OSX** | **iOS** | **watchOS** | **tvOS**
|
||||
<a name="architecture"></a>
|
||||
> *架构* → **i386** | **x86_64** | **arm** | **arm64**
|
||||
> *架构* → **i386** | **x86_64** | **arm** | **arm64**
|
||||
<a name="swift-version"></a>
|
||||
> *swift 版本* → [*十进制数字*](02_Lexical_Structure.md#decimal-digit) **.** [*十进制数字*](02_Lexical_Structure.md#decimal-digit)
|
||||
|
||||
@ -627,28 +627,28 @@ statements to compile if both compilation conditions are false
|
||||
第二种的行控制语句,`#sourceLocation()`,会将源代码的定位信息重置回默认的行号和文件名。
|
||||
|
||||
<a name="line-control-statement"></a>
|
||||
> 行控制语句语法
|
||||
>
|
||||
> *行控制语句* → **#sourceLocation(file:[*文件名*](#file-name),line:[*行号*](#line-number))**
|
||||
> *行控制语句* → **#sourceLocation()**
|
||||
> 行控制语句语法
|
||||
>
|
||||
> *行控制语句* → **#sourceLocation(file:[*文件名*](#file-name),line:[*行号*](#line-number))**
|
||||
> *行控制语句* → **#sourceLocation()**
|
||||
<a name="line-number"></a>
|
||||
> *行号* → 大于 0 的十进制整数
|
||||
> *行号* → 大于 0 的十进制整数
|
||||
<a name="file-name"></a>
|
||||
> *文件名* → [*静态字符串字面量*](02_Lexical_Structure.md#static-string-literal)
|
||||
|
||||
<a name="availability_condition"></a>
|
||||
### 可用性条件
|
||||
|
||||
可用性条件可作为 `if`,`while`,`guard` 语句的条件,可以在运行时基于特定的平台参数来查询 API 的可用性。
|
||||
可用性条件可作为 `if`,`while`,`guard` 语句的条件,可以在运行时基于特定的平台参数来查询 API 的可用性。
|
||||
|
||||
可用性条件的形式如下:
|
||||
|
||||
```swift
|
||||
if #available(platform name version, ..., *) {
|
||||
statements to execute if the APIs are available
|
||||
} else {
|
||||
fallback statements to execute if the APIs are unavailable
|
||||
}
|
||||
if #available(platform name version, ..., *) {
|
||||
statements to execute if the APIs are available
|
||||
} else {
|
||||
fallback statements to execute if the APIs are unavailable
|
||||
}
|
||||
```
|
||||
|
||||
使用可用性条件来执行一个代码块时,取决于使用的 API 在运行时是否可用,编译器会根据可用性条件提供的信息来决定是否执行相应的代码块。
|
||||
@ -657,21 +657,21 @@ if #available(platform name version, ..., *) {
|
||||
|
||||
与布尔类型的条件不同,不能用逻辑运算符 `&&` 和 `||` 组合可用性条件。
|
||||
|
||||
> 可用性条件语法
|
||||
> 可用性条件语法
|
||||
>
|
||||
<a name="availability-condition"></a>
|
||||
> *可用性条件* → **#available** **(** [*可用性参数列表*](#availability-arguments) **)**
|
||||
> *可用性条件* → **#available** **(** [*可用性参数列表*](#availability-arguments) **)**
|
||||
<a name="availability-arguments"></a>
|
||||
> *可用性参数列表* → [*可用性参数*](#availability-argument) | [*可用性参数*](#availability-argument) **,** [*可用性参数列表*](#availability-arguments)
|
||||
> *可用性参数列表* → [*可用性参数*](#availability-argument) | [*可用性参数*](#availability-argument) **,** [*可用性参数列表*](#availability-arguments)
|
||||
<a name="availability-argument"></a>
|
||||
> *可用性参数* → [平台名称](#platform-name) [平台版本](#platform-version)
|
||||
> *可用性参数* → [平台名称](#platform-name) [平台版本](#platform-version)
|
||||
> *可用性条件* → __*__
|
||||
|
||||
<a name="platform-name"></a>
|
||||
> *平台名称* → **iOS** | **iOSApplicationExtension**
|
||||
> *平台名称* → **OSX** | **OSXApplicationExtension**
|
||||
> *平台名称* → **watchOS**
|
||||
> *平台名称* → **iOS** | **iOSApplicationExtension**
|
||||
> *平台名称* → **OSX** | **OSXApplicationExtension**
|
||||
> *平台名称* → **watchOS**
|
||||
<a name="platform-version"></a>
|
||||
> *平台版本* → [十进制数字](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)
|
||||
> *平台版本* → [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits) **.** [十进制数字](02_Lexical_Structure.md#decimal-digits)
|
||||
|
||||
@ -65,22 +65,22 @@
|
||||
|
||||
在 Swift 中,大多数声明在某种意义上讲也是定义,因为声明往往伴随着实现或初始化。由于协议并不提供实现,大多数协议成员仅仅只是声明而已。为了方便起见,也是因为这些区别在 Swift 中并不是很重要,“声明”这个术语同时包含了声明和定义两种含义。
|
||||
|
||||
> 声明语法
|
||||
> 声明语法
|
||||
> <a name="declaration"></a>
|
||||
> *声明* → [*导入声明*](#import-declaration)
|
||||
> *声明* → [*常量声明*](#constant-declaration)
|
||||
> *声明* → [*变量声明*](#variable-declaration)
|
||||
> *声明* → [*类型别名声明*](#typealias-declaration)
|
||||
> *声明* → [*函数声明*](#function-declaration)
|
||||
> *声明* → [*枚举声明*](#enum-declaration)
|
||||
> *声明* → [*结构体声明*](#struct-declaration)
|
||||
> *声明* → [*类声明*](#class-declaration)
|
||||
> *声明* → [*协议声明*](#protocol-declaration)
|
||||
> *声明* → [*构造器声明*](#initializer-declaration)
|
||||
> *声明* → [*析构器声明*](#deinitializer-declaration)
|
||||
> *声明* → [*扩展声明*](#extension-declaration)
|
||||
> *声明* → [*下标声明*](#subscript-declaration)
|
||||
> *声明* → [*运算符声明*](#operator-declaration)
|
||||
> *声明* → [*导入声明*](#import-declaration)
|
||||
> *声明* → [*常量声明*](#constant-declaration)
|
||||
> *声明* → [*变量声明*](#variable-declaration)
|
||||
> *声明* → [*类型别名声明*](#typealias-declaration)
|
||||
> *声明* → [*函数声明*](#function-declaration)
|
||||
> *声明* → [*枚举声明*](#enum-declaration)
|
||||
> *声明* → [*结构体声明*](#struct-declaration)
|
||||
> *声明* → [*类声明*](#class-declaration)
|
||||
> *声明* → [*协议声明*](#protocol-declaration)
|
||||
> *声明* → [*构造器声明*](#initializer-declaration)
|
||||
> *声明* → [*析构器声明*](#deinitializer-declaration)
|
||||
> *声明* → [*扩展声明*](#extension-declaration)
|
||||
> *声明* → [*下标声明*](#subscript-declaration)
|
||||
> *声明* → [*运算符声明*](#operator-declaration)
|
||||
> <a name="declarations"></a>
|
||||
> *多条声明* → [*声明*](#declaration) [*多条声明*](#declarations)<sub>可选</sub>
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
|
||||
Swift 的源文件中的顶级代码 (top-level code) 由零个或多个语句、声明和表达式组成。默认情况下,在一个源文件的顶层声明的变量,常量和其他具有命名的声明可以被同模块中的每一个源文件中的代码访问。可以使用一个访问级别修饰符来标记声明来覆盖这种默认行为,请参阅 [访问控制级别](#access_control_levels)。
|
||||
|
||||
> 顶级声明语法
|
||||
> 顶级声明语法
|
||||
> *顶级声明* → [*多条语句*](10_Statements.md#statements)<sub>可选</sub>
|
||||
|
||||
<a name="code_blocks"></a>
|
||||
@ -104,9 +104,9 @@ Swift 的源文件中的顶级代码 (top-level code) 由零个或多个语句
|
||||
```
|
||||
代码块中的“语句”包括声明、表达式和各种其他类型的语句,它们按照在源码中的出现顺序被依次执行。
|
||||
|
||||
> 代码块语法
|
||||
> 代码块语法
|
||||
> <a name="code-block"></a>
|
||||
> *代码块* → **{** [*多条语句*](10_Statements.md#statements)<sub>可选</sub> **}**
|
||||
> *代码块* → **{** [*多条语句*](10_Statements.md#statements)<sub>可选</sub> **}**
|
||||
|
||||
<a name="import_declaration"></a>
|
||||
## 导入声明
|
||||
@ -125,15 +125,15 @@ import 模块.子模块
|
||||
```
|
||||
|
||||
<a name="grammer_of_an_import_declaration"></a>
|
||||
> 导入声明语法
|
||||
> 导入声明语法
|
||||
> <a name="import-declaration"></a>
|
||||
> *导入声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **import** [*导入类型*](#import-kind)<sub>可选</sub> [*导入路径*](#import-path)
|
||||
> *导入声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **import** [*导入类型*](#import-kind)<sub>可选</sub> [*导入路径*](#import-path)
|
||||
> <a name="import-kind"></a>
|
||||
> *导入类型* → **typealias** | **struct** | **class** | **enum** | **protocol** | **var** | **func**
|
||||
> *导入类型* → **typealias** | **struct** | **class** | **enum** | **protocol** | **var** | **func**
|
||||
> <a name="import-path"></a>
|
||||
> *导入路径* → [*导入路径标识符*](#import-path-identifier) | [*导入路径标识符*](#import-path-identifier) **.** [*导入路径*](#import-path)
|
||||
> *导入路径* → [*导入路径标识符*](#import-path-identifier) | [*导入路径标识符*](#import-path-identifier) **.** [*导入路径*](#import-path)
|
||||
> <a name="import-path-identifier"></a>
|
||||
> *导入路径标识符* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
> *导入路径标识符* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
|
||||
<a name="constant_declaration"></a>
|
||||
## 常量声明
|
||||
@ -170,15 +170,15 @@ print("The second number is \(secondNumber).")
|
||||
如果还想获得更多关于常量的信息或者想在使用中获得帮助,请参阅 [常量和变量](../chapter2/01_The_Basics.md#constants_and_variables) 和 [存储属性](../chapter2/10_Properties.md#stored_properties)。
|
||||
|
||||
<a name="grammer_of_a_constant_declaration"></a>
|
||||
> 常量声明语法
|
||||
> 常量声明语法
|
||||
> <a name="constant-declaration"></a>
|
||||
> *常量声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **let** [*模式构造器列表*](pattern-initializer-list)
|
||||
> *常量声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **let** [*模式构造器列表*](pattern-initializer-list)
|
||||
> <a name="pattern-initializer-list"></a>
|
||||
> *模式构造器列表* → [*模式构造器*](#pattern-initializer) | [*模式构造器*](#pattern-initializer) **,** [*模式构造器列表*](#pattern-initializer-list)
|
||||
> *模式构造器列表* → [*模式构造器*](#pattern-initializer) | [*模式构造器*](#pattern-initializer) **,** [*模式构造器列表*](#pattern-initializer-list)
|
||||
> <a name="pattern-initializer"></a>
|
||||
> *模式构造器* → [*模式*](07_Patterns.md#pattern) [*构造器*](#initializer)<sub>可选</sub>
|
||||
> *模式构造器* → [*模式*](07_Patterns.md#pattern) [*构造器*](#initializer)<sub>可选</sub>
|
||||
> <a name="initializer"></a>
|
||||
> *构造器* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
> *构造器* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="variable_declaration"></a>
|
||||
## 变量声明
|
||||
@ -187,7 +187,8 @@ print("The second number is \(secondNumber).")
|
||||
|
||||
变量声明有几种不同的形式,可以声明不同种类的命名值和可变值,如存储型和计算型变量和属性,属性观察器,以及静态变量属性。所使用的声明形式取决于变量声明的适用范围和打算声明的变量类型。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 也可以在协议声明中声明属性,详情请参阅 [协议属性声明](#protocol_property_declaration)。
|
||||
|
||||
可以在子类中重写继承来的变量属性,使用 `override` 声明修饰符标记属性的声明即可,详情请参阅 [重写](../chapter2/13_Inheritance.md#overriding)。
|
||||
@ -215,14 +216,14 @@ var 变量名称: 类型 = 表达式
|
||||
使用如下形式声明一个计算型变量或计算型属性:
|
||||
|
||||
```swift
|
||||
var 变量名称: 类型 {
|
||||
get {
|
||||
var 变量名称: 类型 {
|
||||
get {
|
||||
语句
|
||||
}
|
||||
set(setter 名称) {
|
||||
}
|
||||
set(setter 名称) {
|
||||
语句
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以在全局范围、函数内部,以及类、结构、枚举、扩展的声明中使用这种形式的声明。当变量以这种形式在全局范围或者函数内部被声明时,它表示一个计算型变量。当它在类、结构、枚举、扩展声明的上下文中被声明时,它表示一个*计算型属性 (computed property)*。
|
||||
@ -241,14 +242,14 @@ setter 的圆括号以及 setter 名称是可选的。如果提供了 setter 名
|
||||
可以在声明存储型变量或属性时提供 `willSet` 和 `didSet` 观察器。一个包含观察器的存储型变量或属性以如下形式声明:
|
||||
|
||||
```swift
|
||||
var 变量名称: 类型 = 表达式 {
|
||||
willSet(setter 名称) {
|
||||
var 变量名称: 类型 = 表达式 {
|
||||
willSet(setter 名称) {
|
||||
语句
|
||||
}
|
||||
didSet(setter 名称) {
|
||||
}
|
||||
didSet(setter 名称) {
|
||||
语句
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以在全局范围、函数内部,或者类、结构的声明中使用这种形式的声明。当变量以这种形式在全局范围或者函数内部被声明时,观察器表示一个存储型变量观察器。当它在类和结构的声明中被声明时,观察器表示一个属性观察器。
|
||||
@ -273,51 +274,52 @@ var 变量名称: 类型 = 表达式 {
|
||||
|
||||
要声明一个类型变量属性,用 `static` 声明修饰符标记该声明。类可以改用 `class` 声明修饰符标记类的类型计算型属性从而允许子类重写超类的实现。类型属性在 [类型属性](../chapter2/10_Properties.md#type_properties) 章节有详细讨论。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 在一个类声明中,使用关键字 `static` 与同时使用 `class` 和 `final` 去标记一个声明的效果相同。
|
||||
|
||||
<a name="grammer_of_a_variable_declaration"></a>
|
||||
> 变量声明语法
|
||||
> 变量声明语法
|
||||
|
||||
<a name="variable-declaration"></a>
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*模式构造器列表*](#pattern-initializer-list)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*代码块*](#code-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter代码块*](#getter-setter-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*构造器*](#initializer) [*willSet-didSet代码块*](#willSet-didSet-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*构造器*](#initializer)<sub>可选</sub> [*willSet-didSet代码块*](#willSet-didSet-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*模式构造器列表*](#pattern-initializer-list)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*代码块*](#code-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter 代码块*](#getter-setter-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter 关键字代码块*](#getter-setter-keyword-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*构造器*](#initializer) [*willSet-didSet 代码块*](#willSet-didSet-block)
|
||||
> *变量声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*构造器*](#initializer)<sub>可选</sub> [*willSet-didSet 代码块*](#willSet-didSet-block)
|
||||
|
||||
<a name="variable-declaration-head"></a>
|
||||
> *变量声明头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **var**
|
||||
> *变量声明头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **var**
|
||||
> <a name="variable-name"></a>
|
||||
> *变量名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *变量名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="getter-setter-block"></a>
|
||||
> *getter-setter 代码块* → [*代码块*](#code-block)
|
||||
> *getter-setter 代码块* → **{** [*getter子句*](#getter-clause) [*setter子句*](#setter-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 代码块* → **{** [*setter子句*](#setter-clause) [*getter子句*](#getter-clause) **}**
|
||||
> *getter-setter 代码块* → [*代码块*](#code-block)
|
||||
> *getter-setter 代码块* → **{** [*getter 子句*](#getter-clause) [*setter 子句*](#setter-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 代码块* → **{** [*setter 子句*](#setter-clause) [*getter 子句*](#getter-clause) **}**
|
||||
> <a name="getter-clause"></a>
|
||||
> *getter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get** [*代码块*](#code-block)
|
||||
> *getter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get** [*代码块*](#code-block)
|
||||
> <a name="setter-clause"></a>
|
||||
> *setter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
> *setter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set** [*setter 名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
> <a name="setter-name"></a>
|
||||
> *setter 名称* → **(** [*标识符*](02_Lexical_Structure.md#identifier) **)**
|
||||
> *setter 名称* → **(** [*标识符*](02_Lexical_Structure.md#identifier) **)**
|
||||
|
||||
<a name="getter-setter-keyword-block"></a>
|
||||
> *getter-setter 关键字代码块* → **{** [*getter关键字子句*](#getter-keyword-clause) [*setter关键字子句*](#setter-keyword-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 关键字代码块* → **{** [*setter关键字子句*](#setter-keyword-clause) [*getter关键字子句*](#getter-keyword-clause) **}**
|
||||
> *getter-setter 关键字代码块* → **{** [*getter 关键字子句*](#getter-keyword-clause) [*setter 关键字子句*](#setter-keyword-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 关键字代码块* → **{** [*setter 关键字子句*](#setter-keyword-clause) [*getter 关键字子句*](#getter-keyword-clause) **}**
|
||||
> <a name="getter-keyword-clause"></a>
|
||||
> *getter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get**
|
||||
> *getter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get**
|
||||
> <a name="setter-keyword-clause"></a>
|
||||
> *setter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set**
|
||||
> *setter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set**
|
||||
|
||||
<a name="willSet-didSet-block"></a>
|
||||
> *willSet-didSet 代码块* → **{** [*willSet子句*](#willSet-clause) [*didSet子句*](#didSet-clause)<sub>可选</sub> **}**
|
||||
> *willSet-didSet 代码块* → **{** [*didSet子句*](#didSet-clause) [*willSet子句*](#willSet-clause)<sub>可选</sub> **}**
|
||||
> *willSet-didSet 代码块* → **{** [*willSet 子句*](#willSet-clause) [*didSet 子句*](#didSet-clause)<sub>可选</sub> **}**
|
||||
> *willSet-didSet 代码块* → **{** [*didSet 子句*](#didSet-clause) [*willSet 子句*](#willSet-clause)<sub>可选</sub> **}**
|
||||
> <a name="willSet-clause"></a>
|
||||
> *willSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **willSet** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
> *willSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **willSet** [*setter 名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
> <a name="didSet-clause"></a>
|
||||
> *didSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **didSet** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
> *didSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **didSet** [*setter 名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
|
||||
<a name="type_alias_declaration"></a>
|
||||
## 类型别名声明
|
||||
@ -353,20 +355,20 @@ func sum<T: Sequence>(_ sequence: T) -> Int where T.Element == Int {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
假如没有类型别名,sum函数将必须引用关联类型通过T.Iterator.Element的形式来替代 T.Element。
|
||||
假如没有类型别名,sum 函数将必须引用关联类型通过 T.Iterator.Element 的形式来替代 T.Element。
|
||||
|
||||
另请参阅 [协议关联类型声明](#protocol_associated_type_declaration)。
|
||||
|
||||
<a name="grammer_of_a_type_alias_declaration"></a>
|
||||
> 类型别名声明语法
|
||||
> 类型别名声明语法
|
||||
> <a name="typealias-declaration"></a>
|
||||
> *类型别名声明* → [*类型别名头*](#typealias-head) [*类型别名赋值*](#typealias-assignment)
|
||||
> *类型别名声明* → [*类型别名头*](#typealias-head) [*类型别名赋值*](#typealias-assignment)
|
||||
> <a name="typealias-head"></a>
|
||||
> *类型别名头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier)<sub>可选</sub> **typealias** [*类型别名名称*](#typealias-name)
|
||||
> *类型别名头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier)<sub>可选</sub> **typealias** [*类型别名名称*](#typealias-name)
|
||||
> <a name="typealias-name"></a>
|
||||
> *类型别名名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *类型别名名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> <a name="typealias-assignment"></a>
|
||||
> *类型别名赋值* → **=** [*类型*](03_Types.md#type)
|
||||
> *类型别名赋值* → **=** [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="function_declaration"></a>
|
||||
## 函数声明
|
||||
@ -374,7 +376,7 @@ func sum<T: Sequence>(_ sequence: T) -> Int where T.Element == Int {
|
||||
使用*函数声明 (function declaration)* 在程序中引入新的函数或者方法。在类、结构体、枚举,或者协议中声明的函数会作为方法。函数声明使用关键字 `func`,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) -> 返回类型 {
|
||||
func 函数名称(参数列表) -> 返回类型 {
|
||||
语句
|
||||
}
|
||||
```
|
||||
@ -382,7 +384,7 @@ func 函数名称(参数列表) -> 返回类型 {
|
||||
如果函数返回 `Void` 类型,返回类型可以省略,如下所示:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) {
|
||||
func 函数名称(参数列表) {
|
||||
语句
|
||||
}
|
||||
```
|
||||
@ -409,7 +411,7 @@ f(1, y: 2) // 参数 y 有标签,参数 x 则没有
|
||||
|
||||
可以按照如下两种形式之一,重写参数名称的默认行为:
|
||||
|
||||
`外部参数名称` `内部参数名称`: `参数类型`
|
||||
`外部参数名称` `内部参数名称`: `参数类型`
|
||||
_ `内部参数名称`: `参数类型`
|
||||
|
||||
在内部参数名称前的名称会作为这个参数的外部名称,这个名称可以和内部参数的名称不同。外部参数名称在函数被调用时必须被使用,即对应的参数在方法或函数被调用时必须有外部名。
|
||||
@ -475,8 +477,8 @@ print(x)
|
||||
|
||||
```swift
|
||||
_ : 参数类型
|
||||
参数名称: 参数类型...
|
||||
参数名称: 参数类型 = 默认参数值
|
||||
参数名称: 参数类型...
|
||||
参数名称: 参数类型 = 默认参数值
|
||||
```
|
||||
|
||||
以下划线(`_`)命名的参数会被显式忽略,无法在函数体内使用。
|
||||
@ -538,46 +540,46 @@ func someFunction(callback: () throws -> Void) rethrows {
|
||||
<a name="functions_that_never_return"></a>
|
||||
### 永不返回的函数
|
||||
|
||||
Swift定义了`Never`类型,它表示函数或者方法不会返回给它的调用者。`Never`返回类型的函数或方法可以称为不归,不归函数、方法要么引发不可恢复的错误,要么永远不停地运作,这会使调用后本应执行得代码就不再执行了。但即使是不归函数、方法,抛错函数和重抛出函数也可以将程序控制转移到合适的`catch`代码块。
|
||||
Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它的调用者。`Never` 返回类型的函数或方法可以称为不归,不归函数、方法要么引发不可恢复的错误,要么永远不停地运作,这会使调用后本应执行得代码就不再执行了。但即使是不归函数、方法,抛错函数和重抛出函数也可以将程序控制转移到合适的 `catch` 代码块。
|
||||
|
||||
不归函数、方法可以在guard语句的else字句中调用,具体讨论在[*Guard语句*](10_Statements.md#guard_statements)。
|
||||
不归函数、方法可以在 guard 语句的 else 字句中调用,具体讨论在[*Guard 语句*](10_Statements.md#guard_statements)。
|
||||
你可以重载一个不归方法,但是新的方法必须保持原有的返回类型和没有返回的行为。
|
||||
|
||||
<a name="grammer_of_a_function_declaration"></a>
|
||||
> 函数声明语法
|
||||
> 函数声明语法
|
||||
|
||||
<a name="function-declaration"></a>
|
||||
> *函数声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*函数签名*](#function-signature) [*函数体*](#function-body)<sub>可选</sub>
|
||||
> *函数声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*函数签名*](#function-signature) [*函数体*](#function-body)<sub>可选</sub>
|
||||
|
||||
<a name="function-head"></a>
|
||||
> *函数头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **func**
|
||||
> *函数头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **func**
|
||||
> <a name="function-name"></a>
|
||||
> *函数名* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
> *函数名* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
|
||||
<a name="function-signature"></a>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **throws**<sub>可选</sub> [*函数结果*](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **rethrows** [*函数结果*](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **throws**<sub>可选</sub> [*函数结果*](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **rethrows** [*函数结果*](#function-result)<sub>可选</sub>
|
||||
> <a name="function-result"></a>
|
||||
> *函数结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
> *函数结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
> <a name="function-body"></a>
|
||||
> *函数体* → [*代码块*](#code-block)
|
||||
> *函数体* → [*代码块*](#code-block)
|
||||
|
||||
<a name="parameter-clauses"></a>
|
||||
> *参数子句列表* → [*参数子句*](#parameter-clause) [*参数子句列表*](#parameter-clauses)<sub>可选</sub>
|
||||
> *参数子句列表* → [*参数子句*](#parameter-clause) [*参数子句列表*](#parameter-clauses)<sub>可选</sub>
|
||||
> <a name="parameter-clause"></a>
|
||||
> *参数子句* → **(** **)** | **(** [*参数列表*](#parameter-list) **)**
|
||||
> *参数子句* → **(** **)** | **(** [*参数列表*](#parameter-list) **)**
|
||||
> <a name="parameter-list"></a>
|
||||
> *参数列表* → [*参数*](#parameter) | [*参数*](#parameter) **,** [*参数列表*](#parameter-list)
|
||||
> *参数列表* → [*参数*](#parameter) | [*参数*](#parameter) **,** [*参数列表*](#parameter-list)
|
||||
> <a name="parameter"></a>
|
||||
> *参数* → **let**<sub>可选</sub> [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) [*默认参数子句*](#default-argument-clause)<sub>可选</sub>
|
||||
> *参数* → **inout** [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation)
|
||||
> *参数* → [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) **...**
|
||||
> *参数* → **let**<sub>可选</sub> [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) [*默认参数子句*](#default-argument-clause)<sub>可选</sub>
|
||||
> *参数* → **inout** [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation)
|
||||
> *参数* → [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) **...**
|
||||
> <a name="external-parameter-name"></a>
|
||||
> *外部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
> *外部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
> <a name="local-parameter-name"></a>
|
||||
> *内部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
> *内部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
> <a name="default-argument-clause"></a>
|
||||
> *默认参数子句* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
> *默认参数子句* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="enumeration_declaration"></a>
|
||||
## 枚举声明
|
||||
@ -651,10 +653,10 @@ enum Tree<T> {
|
||||
以下形式声明了一种枚举类型,其中各个枚举用例的类型均为同一种基本类型:
|
||||
|
||||
```swift
|
||||
enum 枚举名称: 原始值类型, 采纳的协议 {
|
||||
enum 枚举名称: 原始值类型, 采纳的协议 {
|
||||
case 枚举用例1 = 原始值1
|
||||
case 枚举用例2 = 原始值2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在这种形式中,每一个用例块由 `case` 关键字开始,后面紧跟一个或多个以逗号分隔的枚举用例。和第一种形式的枚举用例不同,这种形式的枚举用例包含一个基础值,叫做原始值,各个枚举用例的原始值的类型必须相同。这些原始值的类型通过原始值类型指定,必须表示一个整数、浮点数、字符串或者字符。原始值类型必须符合 `Equatable` 协议和下列字面量转换协议中的一种:整型字面量需符合 `IntergerLiteralConvertible` 协议,浮点型字面量需符合 `FloatingPointLiteralConvertible` 协议,包含任意数量字符的字符串型字面量需符合 `StringLiteralConvertible` 协议,仅包含一个单一字符的字符串型字面量需符合 `ExtendedGraphemeClusterLiteralConvertible` 协议。每一个用例的名字和原始值必须唯一。
|
||||
@ -692,40 +694,40 @@ enum WeekendDay: String {
|
||||
> 枚举声明语法
|
||||
|
||||
<a name="enum-declaration"></a>
|
||||
> *枚举声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier)<sub>可选</sub> [*联合风格枚举*](#union-style-enum)
|
||||
> *枚举声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier)<sub>可选</sub> [*联合风格枚举*](#union-style-enum)
|
||||
> *枚举声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier) <sub>可选</sub> [*原始值风格枚举*](#raw-value-style-enum)
|
||||
|
||||
<a name="union-style-enum"></a>
|
||||
> *联合风格枚举* → **indirect**<sub>可选</sub> **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> **{** [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub> **}**
|
||||
> *联合风格枚举* → **indirect**<sub>可选</sub> **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> **{** [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub> **}**
|
||||
> <a name="union-style-enum-members"></a>
|
||||
> *多个联合风格枚举成员* → [*联合风格枚举成员*](#union-style-enum-member) [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub>
|
||||
> *多个联合风格枚举成员* → [*联合风格枚举成员*](#union-style-enum-member) [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub>
|
||||
> <a name="union-style-enum-member"></a>
|
||||
> *联合风格枚举成员* → [*声明*](#declaration) | [*联合风格枚举用例子句*](#union-style-enum-case-clause)
|
||||
> *联合风格枚举成员* → [*声明*](#declaration) | [*联合风格枚举用例子句*](#union-style-enum-case-clause)
|
||||
> <a name="union-style-enum-case-clause"></a>
|
||||
> *联合风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **indirect**<sub>可选</sub> **case** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
> *联合风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **indirect**<sub>可选</sub> **case** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
> <a name="union-style-enum-case-list"></a>
|
||||
> *联合风格枚举用例列表* → [*联合风格枚举用例*](#union-style-enum-case) | [*联合风格枚举用例*](#union-style-enum-case) **,** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
> *联合风格枚举用例列表* → [*联合风格枚举用例*](#union-style-enum-case) | [*联合风格枚举用例*](#union-style-enum-case) **,** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
> <a name="union-style-enum-case"></a>
|
||||
> *联合风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*元组类型*](03_Types.md#tuple-type)<sub>可选</sub>
|
||||
> *联合风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*元组类型*](03_Types.md#tuple-type)<sub>可选</sub>
|
||||
> <a name="enum-name"></a>
|
||||
> *枚举名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *枚举名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> <a name="enum-case-name"></a>
|
||||
> *枚举用例名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *枚举用例名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="raw-value-style-enum"></a>
|
||||
> *原始值风格枚举* → **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause) **{** [*多个原始值风格枚举成员*](#raw-value-style-enum-members) **}**
|
||||
> *原始值风格枚举* → **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause) **{** [*多个原始值风格枚举成员*](#raw-value-style-enum-members) **}**
|
||||
> <a name="raw-value-style-enum-members"></a>
|
||||
> *多个原始值风格枚举成员* → [*原始值风格枚举成员*](#raw-value-style-enum-member) [*多个原始值风格枚举成员*](#raw-value-style-enum-members)<sub>可选</sub>
|
||||
> *多个原始值风格枚举成员* → [*原始值风格枚举成员*](#raw-value-style-enum-member) [*多个原始值风格枚举成员*](#raw-value-style-enum-members)<sub>可选</sub>
|
||||
> <a name="raw-value-style-enum-member"></a>
|
||||
> *原始值风格枚举成员* → [*声明*](#declaration) | [*原始值风格枚举用例子句*](#raw-value-style-enum-case-clause)
|
||||
> *原始值风格枚举成员* → [*声明*](#declaration) | [*原始值风格枚举用例子句*](#raw-value-style-enum-case-clause)
|
||||
> <a name="raw-value-style-enum-case-clause"></a>
|
||||
> *原始值风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **case** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
> *原始值风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **case** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
> <a name="raw-value-style-enum-case-list"></a>
|
||||
> *原始值风格枚举用例列表* → [*原始值风格枚举用例*](#raw-value-style-enum-case) | [*原始值风格枚举用例*](#raw-value-style-enum-case) **,** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
> *原始值风格枚举用例列表* → [*原始值风格枚举用例*](#raw-value-style-enum-case) | [*原始值风格枚举用例*](#raw-value-style-enum-case) **,** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
> <a name="raw-value-style-enum-case"></a>
|
||||
> *原始值风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*原始值赋值*](#raw-value-assignment)<sub>可选</sub>
|
||||
> *原始值风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*原始值赋值*](#raw-value-assignment)<sub>可选</sub>
|
||||
> <a name="raw-value-assignment"></a>
|
||||
> *原始值赋值* → **=** [*原始值字面量*](#raw-value-literal)
|
||||
> *原始值赋值* → **=** [*原始值字面量*](#raw-value-literal)
|
||||
> <a name="raw-value-literal"></a>
|
||||
> *原始值字面量* → [数字型字面量](02_Lexical_Structure.md#numeric-literal) | [字符串型字面量](02_Lexical_Structure.md#static-string-literal) | [布尔型字面量](02_Lexical_Structure.md#boolean-literal)
|
||||
|
||||
@ -735,7 +737,7 @@ enum WeekendDay: String {
|
||||
使用*结构体声明 (structure declaration)* 可以在程序中引入一个结构体类型。结构体声明使用 `struct` 关键字,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
struct 结构体名称: 采纳的协议 {
|
||||
struct 结构体名称: 采纳的协议 {
|
||||
多条声明
|
||||
}
|
||||
```
|
||||
@ -762,13 +764,13 @@ struct 结构体名称: 采纳的协议 {
|
||||
可以使用扩展声明来扩展结构体类型的行为,请参阅 [扩展声明](#extension_declaration)。
|
||||
|
||||
<a name="grammer_of_a_structure_declaration"></a>
|
||||
> 结构体声明语法
|
||||
> 结构体声明语法
|
||||
> <a name="struct-declaration"></a>
|
||||
> *结构体声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier) <sub>可选</sub> **struct** [*结构体名称*](#struct-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*结构体主体*](#struct-body)
|
||||
> *结构体声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier) <sub>可选</sub> **struct** [*结构体名称*](#struct-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*结构体主体*](#struct-body)
|
||||
> <a name="struct-name"></a>
|
||||
> *结构体名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *结构体名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> <a name="struct-body"></a>
|
||||
> *结构体主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
> *结构体主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="class_declaration"></a>
|
||||
## 类声明
|
||||
@ -776,7 +778,7 @@ struct 结构体名称: 采纳的协议 {
|
||||
可以在程序中使用*类声明 (class declaration)* 来引入一个类。类声明使用关键字 `class`,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
class 类名: 超类, 采纳的协议 {
|
||||
class 类名: 超类, 采纳的协议 {
|
||||
多条声明
|
||||
}
|
||||
```
|
||||
@ -806,13 +808,13 @@ class 类名: 超类, 采纳的协议 {
|
||||
可以使用扩展声明来扩展类的行为,请参阅 [扩展声明](#extension_declaration)。
|
||||
|
||||
<a name="grammer_of_a_class_declaration"></a>
|
||||
> 类声明语法
|
||||
> 类声明语法
|
||||
> <a name="class-declaration"></a>
|
||||
> *类声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **class** [*类名*](#class-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类主体*](#class-body)
|
||||
> *类声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **class** [*类名*](#class-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类主体*](#class-body)
|
||||
> <a name="class-name"></a>
|
||||
> *类名* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *类名* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> <a name="class-body"></a>
|
||||
> *类主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
> *类主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="protocol_declaration"></a>
|
||||
## 协议声明
|
||||
@ -820,16 +822,17 @@ class 类名: 超类, 采纳的协议 {
|
||||
*协议声明 (protocol declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
||||
|
||||
```swift
|
||||
protocol 协议名称: 继承的协议 {
|
||||
protocol 协议名称: 继承的协议 {
|
||||
协议成员声明
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
协议的主体包含零个或多个协议成员声明,这些成员描述了任何采纳该协议的类型必须满足的一致性要求。一个协议可以声明采纳者必须实现的某些属性、方法、构造器以及下标。协议也可以声明各种各样的类型别名,叫做关联类型,它可以指定协议的不同声明之间的关系。协议声明不能包括类、结构体、枚举或者其它协议的声明。协议成员声明会在后面进行讨论。
|
||||
|
||||
协议类型可以继承自任意数量的其它协议。当一个协议类型继承自其它协议的时候,来自其它协议的所有要求会聚合在一起,而且采纳当前协议的类型必须符合所有的这些要求。关于如何使用协议继承的例子,请参阅 [协议继承](../chapter2/22_Protocols.md#protocol_inheritance)。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 也可以使用协议合成类型来聚合多个协议的一致性要求,请参阅 [协议合成类型](03_Types.md#protocol_composition_type) 和 [协议合成](../chapter2/22_Protocols.md#protocol_composition)。
|
||||
|
||||
可以通过类型的扩展声明来采纳协议,从而为之前声明的类型添加协议一致性。在扩展中,必须实现所有采纳协议的要求。如果该类型已经实现了所有的要求,可以让这个扩展声明的主体留空。
|
||||
@ -846,7 +849,8 @@ protocol SomeProtocol: class {
|
||||
|
||||
任何继承自标记有 `class` 关键字的协议的协议也仅能被类类型采纳。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 如果协议已经用 `objc` 特性标记了,`class` 要求就隐式地应用于该协议,无需显式使用 `class` 关键字。
|
||||
|
||||
协议类型是命名的类型,因此它们可以像其他命名类型一样使用,正如 [协议作为类型](../chapter2/22_Protocols.md#protocols_as_types) 所讨论的。然而,不能构造一个协议的实例,因为协议实际上不提供它们指定的要求的实现。
|
||||
@ -854,23 +858,23 @@ protocol SomeProtocol: class {
|
||||
可以使用协议来声明作为代理的类或者结构体应该实现的方法,正如 [委托(代理)模式](../chapter2/22_Protocols.md#delegation) 中所述。
|
||||
|
||||
<a name="grammer_of_a_protocol_declaration"></a>
|
||||
> 协议声明语法
|
||||
> 协议声明语法
|
||||
|
||||
<a name="protocol-declaration"></a>
|
||||
> *协议声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **protocol** [*协议名称*](#protocol-name) [*类型继承子句*](03_Types.html#type-inheritance-clause)<sub>可选</sub> [*协议主体*](#protocol-body)
|
||||
> *协议声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **protocol** [*协议名称*](#protocol-name) [*类型继承子句*](03_Types.html#type-inheritance-clause)<sub>可选</sub> [*协议主体*](#protocol-body)
|
||||
> <a name="protocol-name"></a>
|
||||
> *协议名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *协议名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> <a name="protocol-body"></a>
|
||||
> *协议主体* → **{** [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub> **}**
|
||||
> *协议主体* → **{** [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="protocol-member-declaration"></a>
|
||||
> *协议成员声明* → [*协议属性声明*](#protocol-property-declaration)
|
||||
> *协议成员声明* → [*协议方法声明*](#protocol-method-declaration)
|
||||
> *协议成员声明* → [*协议构造器声明*](#protocol-initializer-declaration)
|
||||
> *协议成员声明* → [*协议下标声明*](#protocol-subscript-declaration)
|
||||
> *协议成员声明* → [*协议关联类型声明*](#protocol-associated-type-declaration)
|
||||
> *协议成员声明* → [*协议属性声明*](#protocol-property-declaration)
|
||||
> *协议成员声明* → [*协议方法声明*](#protocol-method-declaration)
|
||||
> *协议成员声明* → [*协议构造器声明*](#protocol-initializer-declaration)
|
||||
> *协议成员声明* → [*协议下标声明*](#protocol-subscript-declaration)
|
||||
> *协议成员声明* → [*协议关联类型声明*](#protocol-associated-type-declaration)
|
||||
> <a name="protocol-member-declarations"></a>
|
||||
> *协议成员声明列表* → [*协议成员声明*](#protocol-member-declaration) [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub>
|
||||
> *协议成员声明列表* → [*协议成员声明*](#protocol-member-declaration) [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub>
|
||||
|
||||
<a name="protocol_property_declaration"></a>
|
||||
### 协议属性声明
|
||||
@ -888,9 +892,9 @@ var 属性名: 类型 { get set }
|
||||
另请参阅 [变量声明](#variable_declaration)。
|
||||
|
||||
<a name="grammer_of_an_import_declaration"></a>
|
||||
> 协议属性声明语法
|
||||
> 协议属性声明语法
|
||||
> <a name="protocol-property-declaration"></a>
|
||||
> *协议属性声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
> *协议属性声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter 关键字代码块*](#getter-setter-keyword-block)
|
||||
|
||||
<a name="protocol_method_declaration"></a>
|
||||
### 协议方法声明
|
||||
@ -902,9 +906,9 @@ var 属性名: 类型 { get set }
|
||||
另请参阅 [函数声明](#function_declaration)。
|
||||
|
||||
<a name="grammer_of_a_protocol_declaration"></a>
|
||||
> 协议方法声明语法
|
||||
> 协议方法声明语法
|
||||
> <a name="protocol-method-declaration"></a>
|
||||
> *协议方法声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*函数签名*](#function-signature)
|
||||
> *协议方法声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*函数签名*](#function-signature)
|
||||
|
||||
<a name="protocol_initializer_declaration"></a>
|
||||
### 协议构造器声明
|
||||
@ -919,9 +923,9 @@ var 属性名: 类型 { get set }
|
||||
另请参阅 [构造器声明](#initializer_declaration)。
|
||||
|
||||
<a name="grammer_of_a_protocol_initializer_declaration"></a>
|
||||
> 协议构造器声明语法
|
||||
> 协议构造器声明语法
|
||||
> <a name="protocol-initializer-declaration"></a>
|
||||
> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub>
|
||||
> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub>
|
||||
> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **rethrows**
|
||||
|
||||
<a name="protocol_subscript_declaration"></a>
|
||||
@ -938,9 +942,9 @@ subscript (参数列表) -> 返回类型 { get set }
|
||||
另请参阅 [下标声明](#subscript_declaration)。
|
||||
|
||||
<a name="grammer_of_a_protocol_subscript_declaration"></a>
|
||||
> 协议下标声明语法
|
||||
> 协议下标声明语法
|
||||
> <a name="protocol-subscript-declaration"></a>
|
||||
> *协议下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
> *协议下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter 关键字代码块*](#getter-setter-keyword-block)
|
||||
|
||||
<a name="protocol_associated_type_declaration"></a>
|
||||
### 协议关联类型声明
|
||||
@ -950,9 +954,9 @@ subscript (参数列表) -> 返回类型 { get set }
|
||||
另请参阅 [类型别名声明](#type_alias_declaration)。
|
||||
|
||||
<a name="grammer_of_a_protocol_associated_type_declaration"></a>
|
||||
> 协议关联类型声明语法
|
||||
> 协议关联类型声明语法
|
||||
> <a name="protocol-associated-type-declaration"></a>
|
||||
> *协议关联类型声明* → [*类型别名头*](#typealias-head) [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类型别名赋值*](#typealias-assignment)<sub>可选</sub>
|
||||
> *协议关联类型声明* → [*类型别名头*](#typealias-head) [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类型别名赋值*](#typealias-assignment)<sub>可选</sub>
|
||||
|
||||
<a name="initializer_declaration"></a>
|
||||
## 构造器声明
|
||||
@ -964,9 +968,9 @@ subscript (参数列表) -> 返回类型 { get set }
|
||||
采用如下形式声明结构体和枚举的构造器,以及类的指定构造器:
|
||||
|
||||
```swift
|
||||
init(参数列表) {
|
||||
init(参数列表) {
|
||||
构造语句
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
类的指定构造器直接将类的所有属性初始化。它不能调用类中的其他构造器,如果类有超类,则必须调用超类的一个指定构造器。如果该类从它的超类继承了属性,必须在调用超类的指定构造器后才能修改这些属性。
|
||||
@ -978,9 +982,9 @@ init(参数列表) {
|
||||
要为类声明一个便利构造器,用 `convenience` 声明修饰符来标记构造器声明:
|
||||
|
||||
```swift
|
||||
convenience init(参数列表) {
|
||||
convenience init(参数列表) {
|
||||
构造语句
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
便利构造器可以将构造过程委托给另一个便利构造器或一个指定构造器。但是,类的构造过程必须以一个将类中所有属性完全初始化的指定构造器的调用作为结束。便利构造器不能调用超类的构造器。
|
||||
@ -991,7 +995,8 @@ convenience init(参数列表) {
|
||||
|
||||
和方法、属性和下标一样,需要使用 `override` 声明修饰符标记重写的指定构造器。
|
||||
|
||||
> 注意
|
||||
> 注意
|
||||
>
|
||||
> 如果使用 `required` 声明修饰符标记一个构造器,在子类中重写这种构造器时,无需使用 `override` 修饰符。
|
||||
|
||||
就像函数和方法,构造器也可以抛出或者重抛错误,你可以在构造器参数列表的圆括号之后使用 `throws` 或 `rethrows` 关键字来表明相应的抛出行为。
|
||||
@ -1040,16 +1045,16 @@ if let actualInstance = SomeStruct(input: "Hello") {
|
||||
更多关于可失败构造器的信息和例子,请参阅 [可失败构造器](../chapter2/14_Initialization.md#failable_initializers)。
|
||||
|
||||
<a name="grammer_of_an_initializer_declaration"></a>
|
||||
> 构造器声明语法
|
||||
> 构造器声明语法
|
||||
> <a name="initializer-declaration"></a>
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **rethrows**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **rethrows**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
> <a name="initializer-head"></a>
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **?**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **!**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **?**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **!**
|
||||
> <a name="initializer-body"></a>
|
||||
> *构造器主体* → [*代码块*](#code-block)
|
||||
> *构造器主体* → [*代码块*](#code-block)
|
||||
|
||||
<a name="deinitializer_declaration"></a>
|
||||
## 析构器声明
|
||||
@ -1057,7 +1062,7 @@ if let actualInstance = SomeStruct(input: "Hello") {
|
||||
*析构器声明 (deinitializer declaration)* 可以为类声明一个析构器。析构器没有参数,遵循如下格式:
|
||||
|
||||
```swift
|
||||
deinit {
|
||||
deinit {
|
||||
语句
|
||||
}
|
||||
```
|
||||
@ -1071,9 +1076,9 @@ deinit {
|
||||
关于如何在类声明中使用析构器的例子,请参阅 [析构过程](../chapter2/15_Deinitialization.md)。
|
||||
|
||||
<a name="grammer_of_a_deinitializer_declaration"></a>
|
||||
> 析构器声明语法
|
||||
> 析构器声明语法
|
||||
> <a name="deinitializer-declaration"></a>
|
||||
> *析构器声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **deinit** [*代码块*](#code-block)
|
||||
> *析构器声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **deinit** [*代码块*](#code-block)
|
||||
|
||||
<a name="extension_declaration"></a>
|
||||
## 扩展声明
|
||||
@ -1081,18 +1086,19 @@ deinit {
|
||||
*扩展声明 (extension declaration)* 可以扩展一个现存的类型的行为。扩展声明使用关键字 `extension`,遵循如下格式:
|
||||
|
||||
```swift
|
||||
extension 类型名称: 采纳的协议 {
|
||||
extension 类型名称: 采纳的协议 {
|
||||
声明语句
|
||||
}
|
||||
```
|
||||
|
||||
```swift
|
||||
extension 类型名称 where 要求 {
|
||||
extension 类型名称 where 要求 {
|
||||
声明语句
|
||||
}
|
||||
```
|
||||
扩展声明体可包含零个或多个声明语句。这些声明语句可以包括计算型属性、计算型类型属性、实例方法、类型方法、构造器、下标声明,甚至是类、结构体和枚举声明。扩展声明不能包含析构器、协议声明、存储型属性、属性观察器或其他扩展声明。关于扩展声明的详细讨论,以及各种扩展声明的例子,请参阅 [扩展](../chapter2/21_Extensions.md)。
|
||||
|
||||
如果类型为类,结构体,或枚举类型,则扩展声明会扩展相应的类型。如果类型为协议类型,则扩展声明会扩展所有遵守这个协议的类型。在扩展的协议体中声明语句不能使用`final`标识符。
|
||||
如果类型为类,结构体,或枚举类型,则扩展声明会扩展相应的类型。如果类型为协议类型,则扩展声明会扩展所有遵守这个协议的类型。在扩展的协议体中声明语句不能使用 `final` 标识符。
|
||||
|
||||
扩展声明可以为现存的类、结构体、枚举添加协议一致性,但是不能为类添加超类,因此在扩展声明的类型名称的冒号后面仅能指定一个协议列表。
|
||||
|
||||
@ -1101,13 +1107,13 @@ extension 类型名称 where 要求 {
|
||||
扩展声明可以包含构造器声明。这意味着,如果被扩展的类型在其他模块中定义,构造器声明必须委托另一个在那个模块中声明的构造器,以确保该类型能被正确地初始化。
|
||||
|
||||
<a name="grammer_of_an_extension_declaration"></a>
|
||||
> 扩展声明语法
|
||||
> 扩展声明语法
|
||||
> <a name="extension-declaration"></a>
|
||||
> *扩展声明* → [特性](06_Attributes.md#type_attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **extension** [*类型标识符*](03_Types.md#type-identifier) [*类型-继承-子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*扩展主体*](#extension-body)
|
||||
> *扩展声明* → [特性](06_Attributes.md#type_attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **extension** [*类型标识符*](03_Types.md#type-identifier) [*类型-继承-子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*扩展主体*](#extension-body)
|
||||
> <a name="extension-body"></a>
|
||||
> *扩展声明* → [特性](06_Attributes.md#type_attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **extension** [*类型标识符*](03_Types.md#type-identifier) [*泛型-where-子句*](03_Types.md#type-inheritance-clause) [*扩展主体*](#extension-body)
|
||||
> *扩展主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
> *多条声明* → [单条声明](#subscript_declaration) [多条声明](#declarations) <sub>可选</sub>
|
||||
> *扩展声明* → [特性](06_Attributes.md#type_attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **extension** [*类型标识符*](03_Types.md#type-identifier) [*泛型-where-子句*](03_Types.md#type-inheritance-clause) [*扩展主体*](#extension-body)
|
||||
> *扩展主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
> *多条声明* → [单条声明](#subscript_declaration) [多条声明](#declarations) <sub>可选</sub>
|
||||
> *单条声明* → [声明语句](#declarations) | [编译器-控制-语句](10_Statements.md#compiler-control-statement)
|
||||
|
||||
<a name="subscript_declaration"></a>
|
||||
@ -1141,15 +1147,15 @@ subscript (参数列表) -> 返回类型 {
|
||||
更多关于下标的信息和例子,请参阅 [下标](../chapter2/12_Subscripts.md)。
|
||||
|
||||
<a name="grammer_of_a_subscript_declaration"></a>
|
||||
> 下标声明语法
|
||||
> 下标声明语法
|
||||
> <a name="subscript-declaration"></a>
|
||||
> *下标声明* → [*下标头*](#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)
|
||||
> *下标声明* → [*下标头*](#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)
|
||||
> <a name="subscript-head"></a>
|
||||
> *下标头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **subscript** [*参数子句*](#parameter-clause)
|
||||
> *下标头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **subscript** [*参数子句*](#parameter-clause)
|
||||
> <a name="subscript-result"></a>
|
||||
> *下标结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
> *下标结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="operator_declaration"></a>
|
||||
## 运算符声明
|
||||
@ -1168,7 +1174,7 @@ infix operator 运算符名称: 优先级组
|
||||
|
||||
中缀运算符是二元运算符,置于两个运算对象之间,例如加法运算符(`+`)位于表达式 `1 + 2` 的中间。
|
||||
|
||||
中缀运算符可以选择指定优先级组。如果没有为运算符设置优先级组,Swift会设置默认优先级组`DefaultPrecedence`,它的优先级比三目优先级`TernaryPrecedence`要高,更多内容参考[*优先级组声明*](#precedence_group_declaration_modifiers)
|
||||
中缀运算符可以选择指定优先级组。如果没有为运算符设置优先级组,Swift 会设置默认优先级组 `DefaultPrecedence`,它的优先级比三目优先级 `TernaryPrecedence` 要高,更多内容参考[*优先级组声明*](#precedence_group_declaration_modifiers)
|
||||
|
||||
下面的形式声明了一个新的前缀运算符:
|
||||
|
||||
@ -1193,17 +1199,17 @@ postfix operator 运算符名称 {}
|
||||
声明了一个新的运算符以后,需要实现一个跟这个运算符同名的函数来实现这个运算符。如果是实现一个前缀或者后缀运算符,也必须使用相符的 `prefix` 或者 `postfix` 声明修饰符标记函数声明。如果是实现中缀运算符,则不需要使用 `infix` 声明修饰符标记函数声明。关于如何实现一个新的运算符的例子,请参阅 [自定义运算符](../chapter2/25_Advanced_Operators.md#custom_operators)。
|
||||
|
||||
<a name="grammer_of_an_operator_declaration"></a>
|
||||
> 运算符声明语法
|
||||
> 运算符声明语法
|
||||
|
||||
<a name="operator-declaration"></a>
|
||||
> *运算符声明* → [*前缀运算符声明*](#prefix-operator-declaration) | [*后缀运算符声明*](#postfix-operator-declaration) | [*中缀运算符声明*](#infix-operator-declaration)
|
||||
> *运算符声明* → [*前缀运算符声明*](#prefix-operator-declaration) | [*后缀运算符声明*](#postfix-operator-declaration) | [*中缀运算符声明*](#infix-operator-declaration)
|
||||
|
||||
<a name="prefix-operator-declaration"></a>
|
||||
> *前缀运算符声明* → **prefix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
> *前缀运算符声明* → **prefix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
> <a name="postfix-operator-declaration"></a>
|
||||
> *后缀运算符声明* → **postfix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
> *后缀运算符声明* → **postfix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
> <a name="infix-operator-declaration"></a>
|
||||
> *中缀运算符声明* → **infix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** [*中缀运算符属性*](#infix-operator-attributes)<sub>可选</sub> **}**
|
||||
> *中缀运算符声明* → **infix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** [*中缀运算符属性*](#infix-operator-attributes)<sub>可选</sub> **}**
|
||||
|
||||
<a name="infix-operator-group"></a>
|
||||
> *中缀运算符组* → [*优先级组名称*](#precedence-group-name)
|
||||
@ -1212,7 +1218,7 @@ postfix operator 运算符名称 {}
|
||||
|
||||
## 优先级组声明
|
||||
|
||||
*优先级组声明 (A precedence group declaration)* 会向程序的中缀运算符引入一个全新的优先级组。当没有用圆括号分组时,运算符优先级反应了运算符与它的操作数的关系的紧密程度。
|
||||
*优先级组声明 (A precedence group declaration)* 会向程序的中缀运算符引入一个全新的优先级组。当没有用圆括号分组时,运算符优先级反应了运算符与它的操作数的关系的紧密程度。
|
||||
优先级组的声明如下所示:
|
||||
|
||||
```swift
|
||||
@ -1222,38 +1228,40 @@ precedencegroup 优先级组名称{
|
||||
associativity: 结合性
|
||||
assignment: 赋值性
|
||||
}
|
||||
```
|
||||
较低优先级组和较高优先级组的名称说明了新建的优先级组是依赖于现存的优先级组的。 `lowerThan`优先级组的属性只可以引用当前模块外的优先级组。当两个运算符为同一个操作数竞争时,比如表达式`2 + 3 * 5`,优先级更高的运算符将优先参与运算。
|
||||
```
|
||||
|
||||
> 注意
|
||||
> 使用较低和较高优先级组相互联系的优先级组必须保持单一层次关系,但它们不必是线性关系。这意味着优先级组也许会有未定义的相关优先级。这些优先级组的运算符在没有用圆括号分组的情况下是不能紧邻着使用的。
|
||||
较低优先级组和较高优先级组的名称说明了新建的优先级组是依赖于现存的优先级组的。`lowerThan` 优先级组的属性只可以引用当前模块外的优先级组。当两个运算符为同一个操作数竞争时,比如表达式 `2 + 3 * 5`,优先级更高的运算符将优先参与运算。
|
||||
|
||||
Swift定义了大量的优先级组来与标准库的运算符配合使用,例如相加(`+`)和相减(`-`)属于`AdditionPrecedence`组,相乘(`*`)和相除(`/`)属于` MultiplicationPrecedence`组,详细关于Swift标准库中一系列运算符和优先级组内容,参阅[Swift标准库操作符参考](https://developer.apple.com/reference/swift/1851035-swift_standard_library_operators)。
|
||||
> 注意
|
||||
>
|
||||
> 使用较低和较高优先级组相互联系的优先级组必须保持单一层次关系,但它们不必是线性关系。这意味着优先级组也许会有未定义的相关优先级。这些优先级组的运算符在没有用圆括号分组的情况下是不能紧邻着使用的。
|
||||
|
||||
运算符的结合性表示在没有圆括号分组的情况下,同样优先级的一系列运算符是如何被分组的。你可以指定运算符的结合性通过上下文关键字`left`、`right`或者`none`,如果没有指定结合性,默认是`none`关键字。左关联性的运算符是从左至右分组的,例如,相减操作符(-)是左关联性的,所以表达式`4 - 5 - 6`被分组为`(4 - 5) - 6`,得出结果-7。右关联性的运算符是从右往左分组的,指定为`none`结合性的运算符就没有结合性。同样优先级没有结合性的运算符不能相邻出现,例如`<`运算符是`none`结合性,那表示`1 < 2 < 3`就不是一个有效表达式。
|
||||
Swift 定义了大量的优先级组来与标准库的运算符配合使用,例如相加(`+`)和相减(`-`)属于 `AdditionPrecedence` 组,相乘(`*`)和相除(`/`)属于 `MultiplicationPrecedence` 组,详细关于 Swift 标准库中一系列运算符和优先级组内容,参阅[Swift 标准库操作符参考](https://developer.apple.com/reference/swift/1851035-swift_standard_library_operators)。
|
||||
|
||||
优先级组的赋值性表示在包含可选链操作时的运算符优先级。当设为true时,与优先级组对应的运算符在可选链操作中使用和标准库中赋值运算符同样的分组规则,当设为false或者不设置,该优先级组的运算符与不赋值的运算符遵循同样的可选链规则。
|
||||
运算符的结合性表示在没有圆括号分组的情况下,同样优先级的一系列运算符是如何被分组的。你可以指定运算符的结合性通过上下文关键字 `left`、`right` 或者 `none`,如果没有指定结合性,默认是 `none` 关键字。左关联性的运算符是从左至右分组的,例如,相减操作符(-)是左关联性的,所以表达式 `4 - 5 - 6` 被分组为 `(4 - 5) - 6`,得出结果-7。右关联性的运算符是从右往左分组的,指定为 `none` 结合性的运算符就没有结合性。同样优先级没有结合性的运算符不能相邻出现,例如 `<` 运算符是 `none` 结合性,那表示 `1 < 2 < 3` 就不是一个有效表达式。
|
||||
|
||||
优先级组的赋值性表示在包含可选链操作时的运算符优先级。当设为 true 时,与优先级组对应的运算符在可选链操作中使用和标准库中赋值运算符同样的分组规则,当设为 false 或者不设置,该优先级组的运算符与不赋值的运算符遵循同样的可选链规则。
|
||||
|
||||
<a name="grammer_of_a_precedence_group_declaration"></a>
|
||||
> 优先级组声明语法
|
||||
> 优先级组声明语法
|
||||
|
||||
<a name="precedence-group-declaration"></a>
|
||||
> *优先级组声明* → **precedence**[*优先级组名称*](#precedence-group-name){[*多优先级组属性*](#precedence-group-attributes)<sub>可选</sub> }
|
||||
> *优先级组声明* → **precedence**[*优先级组名称*](#precedence-group-name){[*多优先级组属性*](#precedence-group-attributes)<sub>可选</sub> }
|
||||
<a name="precedence-group-attributes"></a>
|
||||
> *优先级组属性* → [*优先级组属性*](#precedence-group-attribute)[*多优先级组属性*](#precedence-group-attributes)<sub>可选</sub> **{** **}**
|
||||
> *优先级组属性* → [*优先级组属性*](#precedence-group-attribute)[*多优先级组属性*](#precedence-group-attributes)<sub>可选</sub> **{** **}**
|
||||
<a name="precedence-group-attribute"></a>
|
||||
> *优先级组属性* → [*优先级组关系*](#precedence-group-relation)
|
||||
> *优先级组属性* → [*优先级组赋值性*](#precedence-group-assignment)
|
||||
> *优先级组属性* → [*优先级组相关性*](#precedence-group-associativity)
|
||||
> *优先级组属性* → [*优先级组关系*](#precedence-group-relation)
|
||||
> *优先级组属性* → [*优先级组赋值性*](#precedence-group-assignment)
|
||||
> *优先级组属性* → [*优先级组相关性*](#precedence-group-associativity)
|
||||
> <a name="precedence-group-relation"></a>
|
||||
> *优先级组关系* → **higherThan:**[*多优先级组名称*](#precedence-group-names)
|
||||
> *优先级组关系* → **lowerThan:**[*多优先级组名称*](#precedence-group-names)
|
||||
> *优先级组关系* → **higherThan:**[*多优先级组名称*](#precedence-group-names)
|
||||
> *优先级组关系* → **lowerThan:**[*多优先级组名称*](#precedence-group-names)
|
||||
> <a name="precedence-group-assignment"></a>
|
||||
> *优先级组赋值* → **assignment:**[*布尔字面值*](02_Lexical_Structure.md#boolean-literal)
|
||||
> *优先级组赋值* → **assignment:**[*布尔字面值*](02_Lexical_Structure.md#boolean-literal)
|
||||
<a name="precedence-group-associativity"></a>
|
||||
> *优先级组结合性* → **associativity:left**
|
||||
> *优先级组结合性* → **associativity:right**
|
||||
> *优先级组结合性* → **associativity:none**
|
||||
> *优先级组结合性* → **associativity:left**
|
||||
> *优先级组结合性* → **associativity:right**
|
||||
> *优先级组结合性* → **associativity:none**
|
||||
<a name="precedence-group-names"></a>
|
||||
> *多优先级组名称* → [*优先级组名称*](#precedence-group-name) | [*优先级组名称*](#precedence-group-name) | [*优先级组名称*](#precedence-group-name)
|
||||
<a name="precedence-group-name"></a>
|
||||
@ -1314,12 +1322,12 @@ Swift 提供了三个级别的访问控制:`public`、`internal` 和 `private`
|
||||
> 声明修饰符的语法
|
||||
|
||||
<a name="declaration-modifier"></a>
|
||||
> *声明修饰符* → **class** | **convenience**| **dynamic** | **final** | **infix** | **lazy** | **mutating** | **nonmutating** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
|
||||
> 声明修饰符 → [*访问级别修饰符*](#access-level-modifier)
|
||||
> *声明修饰符* → **class** | **convenience**| **dynamic** | **final** | **infix** | **lazy** | **mutating** | **nonmutating** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
|
||||
> 声明修饰符 → [*访问级别修饰符*](#access-level-modifier)
|
||||
> <a name="declaration-modifiers"></a>
|
||||
> *声明修饰符列表* → [*声明修饰符*](#declaration-modifier) [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub>
|
||||
|
||||
<a name="access-level-modifier"></a>
|
||||
>访问级别修饰符 → **internal** | **internal ( set )**
|
||||
>访问级别修饰符 → **private** | **private ( set )**
|
||||
>访问级别修饰符 → **public** | **public ( set )**
|
||||
> 访问级别修饰符 → **internal** | **internal ( set )**
|
||||
> 访问级别修饰符 → **private** | **private ( set )**
|
||||
> 访问级别修饰符 → **public** | **public ( set )**
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
> 翻译+校对:[KYawn](https://github.com/KYawn)
|
||||
|
||||
> 2.1
|
||||
> 翻译:[小铁匠Linus](https://github.com/kevin833752)
|
||||
> 翻译:[小铁匠 Linus](https://github.com/kevin833752)
|
||||
|
||||
本页内容包括:
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
- [Interface Builder 使用的声明特性](#declaration_attributes_used_by_interface_builder)
|
||||
- [类型特性](#type_attributes)
|
||||
|
||||
特性提供了有关声明和类型的更多信息。在Swift中有两种特性,分别用于修饰声明和类型。
|
||||
特性提供了有关声明和类型的更多信息。在 Swift 中有两种特性,分别用于修饰声明和类型。
|
||||
|
||||
您可以通过以下方式指定一个特性:符号`@`后跟特性的名称和特性接收的任何参数:
|
||||
您可以通过以下方式指定一个特性:符号 `@` 后跟特性的名称和特性接收的任何参数:
|
||||
|
||||
> @ `特性名`
|
||||
|
||||
@ -50,38 +50,38 @@
|
||||
当然,你也可以用一个星号(*)来表示上面提到的所有平台。
|
||||
其余的参数,可以按照任何顺序出现,并且可以添加关于声明生命周期的附加信息,包括重要事件。
|
||||
|
||||
- `unavailable`参数表示该声明在指定的平台上是无效的。
|
||||
- `unavailable` 参数表示该声明在指定的平台上是无效的。
|
||||
- `introduced` 参数表示指定平台从哪一版本开始引入该声明。格式如下:
|
||||
|
||||
`introduced`=`版本号`
|
||||
`introduced`=` 版本号 `
|
||||
|
||||
*版本号*由一个或多个正整数构成,由句点分隔的。
|
||||
|
||||
- `deprecated`参数表示指定平台从哪一版本开始弃用该声明。格式如下:
|
||||
- `deprecated` 参数表示指定平台从哪一版本开始弃用该声明。格式如下:
|
||||
|
||||
`deprecated`=`版本号`
|
||||
`deprecated`=` 版本号 `
|
||||
|
||||
可选的*版本号*由一个或多个正整数构成,由句点分隔的。省略版本号表示该声明目前已弃用,当弃用出现时无需给出任何有关信息。如果你省略了版本号,冒号(:)也可省略。
|
||||
|
||||
- `obsoleted` 参数表示指定平台从哪一版本开始废弃该声明。当一个声明被废弃后,它就从平台中移除,不能再被使用。格式如下:
|
||||
|
||||
`obsoleted`=`版本号`
|
||||
`obsoleted`=` 版本号 `
|
||||
|
||||
*版本号*由一个或多个正整数构成,由句点分隔的。
|
||||
|
||||
- `message` 参数用来提供文本信息。当使用被弃用或者被废弃的声明时,编译器会抛出警告或错误信息。格式如下:
|
||||
|
||||
`message`=`信息内容`
|
||||
`message`=` 信息内容 `
|
||||
|
||||
信息内容由一个字符串构成。
|
||||
|
||||
- `renamed` 参数用来提供文本信息,用以表示被重命名的声明的新名字。当使用声明的旧名字时,编译器会报错提示新名字。格式如下:
|
||||
|
||||
`renamed`=`新名字`
|
||||
`renamed`=` 新名字 `
|
||||
|
||||
新名字由一个字符串构成。
|
||||
|
||||
你可以将`renamed` 参数和 `unavailable` 参数以及类型别名声明组合使用,以此向用户表示某个声明已经被重命名。当某个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当有用。
|
||||
你可以将 `renamed` 参数和 `unavailable` 参数以及类型别名声明组合使用,以此向用户表示某个声明已经被重命名。当某个声明的名字在一个框架或者库的不同发布版本间发生变化时,这会相当有用。
|
||||
|
||||
```swift
|
||||
// 首发版本
|
||||
@ -120,7 +120,7 @@ class MyClass {
|
||||
|
||||
`GKInspectable`
|
||||
|
||||
应用此属性,暴露一个自定义GameplayKit组件属性给SpriteKit编辑器UI。
|
||||
应用此属性,暴露一个自定义 GameplayKit 组件属性给 SpriteKit 编辑器 UI。
|
||||
|
||||
`objc`
|
||||
|
||||
@ -153,7 +153,7 @@ var enabled: Bool {
|
||||
|
||||
在类上使用该特性表示该类是应用程序委托类,使用该特性与调用 `NSApplicationMain`(\_:_:) 函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
|
||||
|
||||
如果你不想使用这个特性,可以提供一个 main.swift 文件,并在代码**顶层**调用`NSApplicationMain`(\_:_:) 函数,如下所示:
|
||||
如果你不想使用这个特性,可以提供一个 main.swift 文件,并在代码**顶层**调用 `NSApplicationMain`(\_:_:) 函数,如下所示:
|
||||
|
||||
```swift
|
||||
import AppKit
|
||||
@ -167,26 +167,26 @@ NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
||||
|
||||
`NSManaged`
|
||||
|
||||
该特性用于修饰 `NSManagedObject` 子类中的实例方法或存储型变量属性,表明它们的实现由 `Core Data` 在运行时基于相关实体描述动态提供。对于标记了 `NSManaged` 特性的属性,`Core Data` 也会在运行时为其提供存储。应用这个特性也意味着`objc`特性。
|
||||
该特性用于修饰 `NSManagedObject` 子类中的实例方法或存储型变量属性,表明它们的实现由 `Core Data` 在运行时基于相关实体描述动态提供。对于标记了 `NSManaged` 特性的属性,`Core Data` 也会在运行时为其提供存储。应用这个特性也意味着 `objc` 特性。
|
||||
|
||||
`testable`
|
||||
|
||||
在导入允许测试的编译模块时,该特性用于修饰 `import` 声明,这样就能访问被导入模块中的任何标有 `internal` 访问级别修饰符的实体,犹如它们被标记了 `public` 访问级别修饰符。测试也可以访问使用`internal`或者`public`访问级别修饰符标记的类和类成员,就像它们是`open`访问修饰符声明的。
|
||||
在导入允许测试的编译模块时,该特性用于修饰 `import` 声明,这样就能访问被导入模块中的任何标有 `internal` 访问级别修饰符的实体,犹如它们被标记了 `public` 访问级别修饰符。测试也可以访问使用 `internal` 或者 `public` 访问级别修饰符标记的类和类成员,就像它们是 `open` 访问修饰符声明的。
|
||||
|
||||
`UIApplicationMain`
|
||||
|
||||
在类上使用该特性表示该类是应用程序委托类,使用该特性与调用 `UIApplicationMain`函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
|
||||
在类上使用该特性表示该类是应用程序委托类,使用该特性与调用 `UIApplicationMain` 函数并且把该类的名字作为委托类的名字传递给函数的效果相同。
|
||||
|
||||
如果你不想使用这个特性,可以提供一个 main.swift 文件,并在代码顶层调用 `UIApplicationMain`(\_:\_:\_:) 函数。比如,如果你的应用程序使用一个继承于 UIApplication 的自定义子类作为主要类,你可以调用 `UIApplicationMain`(\_:\_:\_:) 函数而不是使用该特性。
|
||||
|
||||
<a name="declaration_attributes_used_by_interface_builder"></a>
|
||||
###Interface Builder 使用的声明特性
|
||||
|
||||
`Interface Builder` 特性是 `Interface Builder` 用来与 Xcode 同步的声明特性。`Swift` 提供了以下的 `Interface Builder` 特性:`IBAction`,`IBOutlet`,`IBDesignable`,以及`IBInspectable` 。这些特性与 Objective-C 中对应的特性在概念上是相同的。
|
||||
`Interface Builder` 特性是 `Interface Builder` 用来与 Xcode 同步的声明特性。`Swift` 提供了以下的 `Interface Builder` 特性:`IBAction`,`IBOutlet`,`IBDesignable`,以及 `IBInspectable` 。这些特性与 Objective-C 中对应的特性在概念上是相同的。
|
||||
|
||||
`IBOutlet` 和 `IBInspectable` 用于修饰一个类的属性声明,`IBAction` 特性用于修饰一个类的方法声明,`IBDesignable` 用于修饰类的声明。
|
||||
|
||||
`IBAction` 和 `IBOutlet` 特性都意味着`objc`特性。
|
||||
`IBAction` 和 `IBOutlet` 特性都意味着 `objc` 特性。
|
||||
|
||||
<a name="type_attributes"></a>
|
||||
##类型特性
|
||||
@ -213,7 +213,7 @@ convention 特性总是与下面的参数之一一起出现。
|
||||
`escaping`
|
||||
在函数或者方法声明上使用该特性,它表示参数将不会被存储以供延迟执行,这将确保参数不会超出函数调用的生命周期。在使用 `escaping` 声明特性的函数类型中访问属性和方法时不需要显式地使用 `self.`。关于如何使用 `escaping` 特性的例子,请参阅 [逃逸闭包](http://wiki.jikexueyuan.com/project/swift/chapter2/07_Closures.html)。
|
||||
|
||||
>特性语法
|
||||
> 特性语法
|
||||
|
||||
> *特性 *→ @ <font color = 0x3386c8>特性名 特性参数子句</font><sub>可选</sub>
|
||||
|
||||
|
||||
@ -30,16 +30,16 @@ Swift 中的模式分为两类:一种能成功匹配任何类型的值,另
|
||||
|
||||
第二类模式用于全模式匹配,这种情况下你试图匹配的值在运行时可能不存在。此类模式包括枚举用例模式、可选模式、表达式模式和类型转换模式。你在 `switch` 语句的 `case` 标签中,`do` 语句的 `catch` 子句中,或者在 `if`、`while`、`guard` 和 `for-in` 语句的 `case` 条件句中使用这类模式。
|
||||
|
||||
> 模式语法
|
||||
> 模式语法
|
||||
<a name="pattern"></a>
|
||||
> *模式* → [*通配符模式*](#wildcard_pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*标识符模式*](#identifier_pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*值绑定模式*](#value-binding-pattern)
|
||||
> *模式* → [*元组模式*](#tuple-pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*枚举用例模式*](#enum-case-pattern)
|
||||
> *模式* → [*可选模式*](#optional-pattern)
|
||||
> *模式* → [*类型转换模式*](#type-casting-pattern)
|
||||
> *模式* → [*表达式模式*](#expression-pattern)
|
||||
> *模式* → [*通配符模式*](#wildcard_pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*标识符模式*](#identifier_pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*值绑定模式*](#value-binding-pattern)
|
||||
> *模式* → [*元组模式*](#tuple-pattern) [*类型标注*](03_Types.md#type-annotation)<sub>可选</sub>
|
||||
> *模式* → [*枚举用例模式*](#enum-case-pattern)
|
||||
> *模式* → [*可选模式*](#optional-pattern)
|
||||
> *模式* → [*类型转换模式*](#type-casting-pattern)
|
||||
> *模式* → [*表达式模式*](#expression-pattern)
|
||||
|
||||
<a name="wildcard_pattern"></a>
|
||||
## 通配符模式(Wildcard Pattern)
|
||||
@ -52,9 +52,9 @@ for _ in 1...3 {
|
||||
}
|
||||
```
|
||||
|
||||
> 通配符模式语法
|
||||
> 通配符模式语法
|
||||
<a name="wildcard-pattern"></a>
|
||||
> *通配符模式* → **_**
|
||||
> *通配符模式* → **_**
|
||||
|
||||
<a name="identifier_pattern"></a>
|
||||
## 标识符模式(Identifier Pattern)
|
||||
@ -69,9 +69,9 @@ let someValue = 42
|
||||
|
||||
如果一个变量或常量声明的左边是一个标识符模式,那么这个标识符模式是值绑定模式的子模式。
|
||||
|
||||
> 标识符模式语法
|
||||
> 标识符模式语法
|
||||
<a name="identifier-pattern"></a>
|
||||
> *标识符模式* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
> *标识符模式* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="value-binding_pattern"></a>
|
||||
## 值绑定模式(Value-Binding Pattern)
|
||||
@ -92,9 +92,9 @@ case let (x, y):
|
||||
|
||||
在上面这个例子中,`let` 会分配到元组模式 `(x, y)` 中的各个标识符模式。因此,`switch` 语句中 `case let (x, y):` 和 `case (let x, let y):` 的匹配效果是一样的。
|
||||
|
||||
> 值绑定模式语法
|
||||
> 值绑定模式语法
|
||||
<a name="value-binding-pattern"></a>
|
||||
> *值绑定模式* → **var** [*模式*](#pattern) | **let** [*模式*](#pattern)
|
||||
> *值绑定模式* → **var** [*模式*](#pattern) | **let** [*模式*](#pattern)
|
||||
|
||||
<a name="tuple_pattern"></a>
|
||||
## 元组模式
|
||||
@ -121,13 +121,13 @@ let (a) = 2 // a: Int = 2
|
||||
let (a): Int = 2 // a: Int = 2
|
||||
```
|
||||
|
||||
> 元组模式语法
|
||||
> 元组模式语法
|
||||
<a name="tuple-pattern"></a>
|
||||
> *元组模式* → **(** [*元组模式元素列表*](#tuple-pattern-element-list)<sub>可选</sub> **)**
|
||||
> *元组模式* → **(** [*元组模式元素列表*](#tuple-pattern-element-list)<sub>可选</sub> **)**
|
||||
<a name="tuple-pattern-element-list"></a>
|
||||
> *元组模式元素列表* → [*元组模式元素*](#tuple-pattern-element) | [*元组模式元素*](#tuple-pattern-element) **,** [*元组模式元素列表*](#tuple-pattern-element-list)
|
||||
> *元组模式元素列表* → [*元组模式元素*](#tuple-pattern-element) | [*元组模式元素*](#tuple-pattern-element) **,** [*元组模式元素列表*](#tuple-pattern-element-list)
|
||||
<a name="tuple-pattern-element"></a>
|
||||
> *元组模式元素* → [*模式*](#pattern)
|
||||
> *元组模式元素* → [*模式*](#pattern)
|
||||
|
||||
<a name="enumeration_case_pattern"></a>
|
||||
## 枚举用例模式(Enumeration Case Pattern)
|
||||
@ -136,9 +136,9 @@ let (a): Int = 2 // a: Int = 2
|
||||
|
||||
如果你准备匹配的枚举用例有任何关联的值,则相应的枚举用例模式必须指定一个包含每个关联值元素的元组模式。关于使用 `switch` 语句来匹配包含关联值的枚举用例的例子,请参阅 [关联值](../chapter2/08_Enumerations.md#associated_values)。
|
||||
|
||||
> 枚举用例模式语法
|
||||
> 枚举用例模式语法
|
||||
<a name="enum-case-pattern"></a>
|
||||
> *枚举用例模式* → [*类型标识*](03_Types.md#type-identifier)<sub>可选</sub> **.** [*枚举用例名*](05_Declarations.md#enum-case-name) [*元组模式*](#tuple-pattern)<sub>可选</sub>
|
||||
> *枚举用例模式* → [*类型标识*](03_Types.md#type-identifier)<sub>可选</sub> **.** [*枚举用例名*](05_Declarations.md#enum-case-name) [*元组模式*](#tuple-pattern)<sub>可选</sub>
|
||||
|
||||
<a name="optional_pattern"></a>
|
||||
## 可选模式(Optional Pattern)
|
||||
@ -173,7 +173,7 @@ for case let number? in arrayOfOptinalInts {
|
||||
// Found a 5
|
||||
```
|
||||
|
||||
> 可选模式语法
|
||||
> 可选模式语法
|
||||
<a name="optional-pattern"></a>
|
||||
> *可选模式* → [*标识符模式*](03_Types.md#type-identifier) **?**
|
||||
|
||||
@ -182,7 +182,7 @@ for case let number? in arrayOfOptinalInts {
|
||||
|
||||
有两种类型转换模式,`is` 模式和 `as` 模式。`is` 模式只出现在 `switch` 语句中的 `case` 标签中。`is` 模式和 `as` 模式形式如下:
|
||||
|
||||
> is `类型`
|
||||
> is `类型`
|
||||
> `模式` as `类型`
|
||||
|
||||
`is` 模式仅当一个值的类型在运行时和 `is` 模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。`is` 模式和 `is` 运算符有相似表现,它们都进行类型转换,但是 `is` 模式没有返回类型。
|
||||
@ -191,13 +191,13 @@ for case let number? in arrayOfOptinalInts {
|
||||
|
||||
关于使用 `switch` 语句配合 `is` 模式和 `as` 模式来匹配值的例子,请参阅 [Any 和 AnyObject 的类型转换](../chapter2/19_Type_Casting.md#type_casting_for_any_and_anyobject)。
|
||||
|
||||
> 类型转换模式语法
|
||||
> 类型转换模式语法
|
||||
<a name="type-casting-pattern"></a>
|
||||
> *类型转换模式* → [*is模式*](#is-pattern) | [*as模式*](#as-pattern)
|
||||
> *类型转换模式* → [*is 模式*](#is-pattern) | [*as 模式*](#as-pattern)
|
||||
<a name="is-pattern"></a>
|
||||
> *is模式* → **is** [*类型*](03_Types.md#type)
|
||||
> *is 模式* → **is** [*类型*](03_Types.md#type)
|
||||
<a name="as-pattern"></a>
|
||||
> *as模式* → [*模式*](#pattern) **as** [*类型*](03_Types.md#type)
|
||||
> *as 模式* → [*模式*](#pattern) **as** [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="expression_pattern"></a>
|
||||
## 表达式模式(Expression Pattern)
|
||||
@ -236,6 +236,6 @@ default:
|
||||
// 打印 “The point is at (1, 2).”
|
||||
```
|
||||
|
||||
> 表达式模式语法
|
||||
> 表达式模式语法
|
||||
<a name="expression-pattern"></a>
|
||||
> *表达式模式* → [*表达式*](04_Expressions.md#expression)
|
||||
> *表达式模式* → [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
泛型形参子句指定泛型类型或函数的类型形参,以及这些参数相关的约束和要求。泛型形参子句用尖括号(`<>`)包住,形式如下:
|
||||
|
||||
> <`泛型形参列表`>
|
||||
> <`泛型形参列表`>
|
||||
|
||||
泛型形参列表中泛型形参用逗号分开,其中每一个采用以下形式:
|
||||
|
||||
@ -45,7 +45,7 @@ func simpleMax<T: Comparable>(_ x: T, _ y: T) -> T {
|
||||
}
|
||||
```
|
||||
|
||||
例如,因为 `Int` 和 `Double` 均满足`Comparable`协议,所以该函数可以接受这两种类型。与泛型类型相反,调用泛型函数或构造器时不需要指定泛型实参子句。类型实参由传递给函数或构造器的实参推断而出。
|
||||
例如,因为 `Int` 和 `Double` 均满足 `Comparable` 协议,所以该函数可以接受这两种类型。与泛型类型相反,调用泛型函数或构造器时不需要指定泛型实参子句。类型实参由传递给函数或构造器的实参推断而出。
|
||||
|
||||
```swift
|
||||
simpleMax(17, 42) // T 被推断为 Int 类型
|
||||
@ -59,39 +59,39 @@ simpleMax(3.14159, 2.71828) // T 被推断为 Double 类型
|
||||
|
||||
> `where` : `类型要求`
|
||||
|
||||
`where` 子句中的要求用于指明该类型形参继承自某个类或符合某个协议或协议组合。尽管 `where` 子句提供了语法糖使其有助于表达类型形参上的简单约束(如 `<T: Comparable>` 等同于 `<T> where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束,例如你可以强制形参的关联类型遵守协议,如,` <S: Sequence> where S.Iterator.Element: Equatable` 表示泛型类型 `S` 遵守`Sequence`协议并且关联类型`S.Iterator.Element`遵守`Equatable`协议,这个约束确保队列的每一个元素都是符合 `Equatable` 协议的。
|
||||
`where` 子句中的要求用于指明该类型形参继承自某个类或符合某个协议或协议组合。尽管 `where` 子句提供了语法糖使其有助于表达类型形参上的简单约束(如 `<T: Comparable>` 等同于 `<T> where T: Comparable`,等等),但是依然可以用来对类型形参及其关联类型提供更复杂的约束,例如你可以强制形参的关联类型遵守协议,如,`<S: Sequence> where S.Iterator.Element: Equatable` 表示泛型类型 `S` 遵守 `Sequence` 协议并且关联类型 `S.Iterator.Element` 遵守 `Equatable` 协议,这个约束确保队列的每一个元素都是符合 `Equatable` 协议的。
|
||||
|
||||
也可以用操作符 `==` 来指定两个类型必须相同。例如,泛型形参子句 ` <S1: Sequence, S2: Sequence> where S1.Iterator.Element == S2.Iterator.Element` 表示 `S1` 和 `S2` 必须都符合 `SequenceType` 协议,而且两个序列中的元素类型必须相同。
|
||||
也可以用操作符 `==` 来指定两个类型必须相同。例如,泛型形参子句 `<S1: Sequence, S2: Sequence> 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)
|
||||
更多关于泛型 where 从句的信息和关于泛型函数声明的例子,可以看一看 [泛型 where 子句](https://github.com/numbbbbb/the-swift-programming-language-in-chinese/blob/gh-pages/source/chapter2/23_Generics.md#where_clauses)
|
||||
|
||||
> 泛型形参子句语法
|
||||
> 泛型形参子句语法
|
||||
|
||||
<a name="generic-parameter-clause"></a>
|
||||
> *泛型形参子句* → **<** [*泛型形参列表*](#generic-parameter-list) [*约束子句*](#requirement-clause)<sub>可选</sub> **>**
|
||||
> *泛型形参子句* → **<** [*泛型形参列表*](#generic-parameter-list) [*约束子句*](#requirement-clause)<sub>可选</sub> **>**
|
||||
<a name="generic-parameter-list"></a>
|
||||
> *泛型形参列表* → [*泛形形参*](#generic-parameter) | [*泛形形参*](#generic-parameter) **,** [*泛型形参列表*](#generic-parameter-list)
|
||||
> *泛型形参列表* → [*泛形形参*](#generic-parameter) | [*泛形形参*](#generic-parameter) **,** [*泛型形参列表*](#generic-parameter-list)
|
||||
<a name="generic-parameter"></a>
|
||||
> *泛形形参* → [*类型名称*](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)
|
||||
> *泛形形参* → [*类型名称*](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)
|
||||
|
||||
<a name="requirement-clause"></a>
|
||||
> *约束子句* → **where** [*约束列表*](#requirement-list)
|
||||
> *约束子句* → **where** [*约束列表*](#requirement-list)
|
||||
<a name="requirement-list"></a>
|
||||
> *约束列表* → [*约束*](#requirement) | [*约束*](#requirement) **,** [*约束列表*](#requirement-list)
|
||||
> *约束列表* → [*约束*](#requirement) | [*约束*](#requirement) **,** [*约束列表*](#requirement-list)
|
||||
<a name="requirement"></a>
|
||||
> *约束* → [*一致性约束*](#conformance-requirement) | [*同类型约束*](#same-type-requirement)
|
||||
> *约束* → [*一致性约束*](#conformance-requirement) | [*同类型约束*](#same-type-requirement)
|
||||
|
||||
<a name="conformance-requirement"></a>
|
||||
> *一致性约束* → [*类型标识符*](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-identifier)
|
||||
> *一致性约束* → [*类型标识符*](03_Types.html#type-identifier) **:** [*协议合成类型*](03_Types.html#protocol-composition-type)
|
||||
<a name="same-type-requirement"></a>
|
||||
> *同类型约束* → [*类型标识符*](03_Types.html#type-identifier) **==** [*类型*](03_Types.html#type)
|
||||
> *同类型约束* → [*类型标识符*](03_Types.html#type-identifier) **==** [*类型*](03_Types.html#type)
|
||||
|
||||
<a name="generic_argument"></a>
|
||||
## 泛型实参子句
|
||||
@ -118,10 +118,10 @@ let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
|
||||
如 [泛型形参子句](#generic_parameter) 所述,不能用泛型实参子句来指定泛型函数或构造器的类型实参。
|
||||
|
||||
> 泛型实参子句语法
|
||||
> 泛型实参子句语法
|
||||
<a name="generic-argument-clause"></a>
|
||||
> *泛型实参子句* → **<** [*泛型实参列表*](#generic-argument-list) **>**
|
||||
> *泛型实参子句* → **<** [*泛型实参列表*](#generic-argument-list) **>**
|
||||
<a name="generic-argument-list"></a>
|
||||
> *泛型实参列表* → [*泛型实参*](#generic-argument) | [*泛型实参*](#generic-argument) **,** [*泛型实参列表*](#generic-argument-list)
|
||||
> *泛型实参列表* → [*泛型实参*](#generic-argument) | [*泛型实参*](#generic-argument) **,** [*泛型实参列表*](#generic-argument-list)
|
||||
<a name="generic-argument"></a>
|
||||
> *泛型实参* → [*类型*](03_Types.html#type)
|
||||
> *泛型实参* → [*类型*](03_Types.html#type)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user