This commit is contained in:
949478479
2015-12-02 23:01:30 +08:00
parent ff9cf6f92c
commit 60a3b11a4d

View File

@ -16,74 +16,81 @@
- [空白与注释(*Whitespace and Comments*](#whitespace_and_comments)
- [标识符(*Identifiers*](#identifiers)
- [关键字(*Keywords*](#keywords)
- [关键字和标点符号*Keywords and Punctuation*](#keywords)
- [字面量(*Literals*](#literals)
- [运算符(*Operators*](#operators)
Swift 的“词法结构(*lexical structure*)”描述了能构成该语言中合法标记(*tokens*的字符序列。这些合法标记组成了语言中最底层的构建基块,并在之后的章节中用于描述语言的其他部分。一个合法标记由一个标识符、关键字、标点符号、字或运算符组成。
Swift 的“词法结构(*lexical structure*)”描述了能构成该语言中合法符号的字符序列。这些合法符号组成了语言中最底层的构建基块,并在之后的章节中用于描述语言的其他部分。一个合法符号由一个标识符、关键字、标点符号、字面量或运算符组成。
通常情况下,标记是在随后将介绍的语法约束,由 Swift 源文件的输入文本中提取可能的最长子串生成。这种方法称为“最长匹配*longest match*)”,或者“最大适合”(*maximal munch*)。
通常情况下,符号是根据随后将介绍的语法约束,由 Swift 源文件的输入文本中提取可能的最长子串生成。这种方法称为“最长匹配(*longest match*)”,或者“最大适合”(*maximal munch*)。
<a id="whitespace_and_comments"></a>
## 空白与注释
空白(*whitespace*)有两个用途:分隔源文件中的标记和帮助区分运算符属于前缀还是后缀(参见 [运算符](#operators)),在其他情况下则会被忽略。以下的字符会被当作空白:空格(*space*U+0020、换行符*line feed*U+000A、回车符*carriage return*U+000D、水平制表符*horizontal tab*U+0009、垂直制表符*vertical tab*U+000B、换页符*form feed*U+000C以及空*null*U+0000
空白(*whitespace*)有两个用途:分隔源文件中的符号以及帮助区分运算符属于前缀还是后缀(参见 [运算符](#operators)在其他情况下则会被忽略。以下的字符会被当作空白空格U+0020、换行符U+000A、回车符U+000D、水平制表符U+0009、垂直制表符U+000B、换页符U+000C以及空U+0000
注释(*comments*)被编译器当作空白处理。单行注释由 `//` 开始直至遇到换行符(*line feed*U+000A或者回车符*carriage return*U+000D。多行注释由 `/*` 开始,以 `*/` 结束。注释允许嵌套,但注释标记必须匹配。
注释(*comments*)被编译器当作空白处理。单行注释由 `//` 开始直至遇到换行符(U+000A或者回车符U+000D。多行注释由 `/*` 开始,以 `*/` 结束。注释允许嵌套,但注释标记必须匹配。
就像 [标记格式引用Markup Formatting Reference](https://developer.apple.com/library/prerelease/ios/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html#//apple_ref/doc/uid/TP40016497) 所说的那样,注释可以包含附加的格式和标记。
正如 [标记格式参考Markup Formatting Reference](https://developer.apple.com/library/prerelease/ios/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html#//apple_ref/doc/uid/TP40016497) 所,注释可以包含附加的格式和标记。
<a id="identifiers"></a>
## 标识符
标识符(*identifiers*)可以由以下的字符开始:大写或小写的字母 `A``Z`、下划线 `_`、基本多文种平面(*Basic Multilingual Plane*)中的 Unicode 非组合字符以及基本多文种平面以外的非专用区(*Private Use Area*)字符。首字符之后,允许使用数字和 Unicode 字符组合。
标识符(*identifiers*)可以由以下的字符开始:大写或小写的字母 `A``Z`、下划线 `_`、基本多文种平面(*Basic Multilingual Plane*)中的 Unicode 非组合字符以及基本多文种平面以外的非个人专用区(*Private Use Area*)字符。首字符之后,允许使用数字和 Unicode 字符组合。
使用保留字(*reserved word*)作为标识符,需要在其前后增加反引号 \`。例如,`class` 不是合法的标识符,但可以使用 \`class\`。反引号不属于标识符的一部分,\`x\` 和 `x` 表示同一标识符。
使用保留字(*reserved word*)作为标识符,需要在其前后增加反引号 `` ` ``。例如,`class` 不是合法的标识符,但可以使用 `` `class` ``。反引号不属于标识符的一部分,`` `x` `` 和 `x` 表示同一标识符。
闭包(*closure*)中如果没有明确指定参数名称,参数将被隐式命名为 `$0``$1``$2`等等。 这些命名在闭包作用域范围内是合法的标识符。
闭包(*closure*)中如果没有明确指定参数名称,参数将被隐式命名为 `$0`、`$1`、`$2` 等等。这些命名在闭包作用域范围内是合法的标识符。
> 标识符语法
> 标识符语法
<a id="identifier"></a>
> *标识符* → [*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters)<sub>可选</sub>
> *标识符* → \`[*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters)<sub>可选</sub>\`
> *标识符* → [*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters) <sub>可选</sub>
> *标识符* → \`[*头部标识符*](#identifier_head) [*标识符字符组*](#identifier_characters) <sub>可选</sub>\`
> *标识符* → [*隐式参数名*](#implicit_parameter_name)
> *标识符列表* → [*标识符*](#identifier) | [*标识符*](#identifier) **,** [*标识符列表*](#identifier_list)
<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+00B2U+00B5, or U+00B7U+00BA
> *头部标识符* → U+00BCU+00BE, U+00C0U+00D6, U+00D8U+00F6, or U+00F8U+00FF
> *头部标识符* → U+0100U+02FF, U+0370U+167F, U+1681U+180D, or U+180FU+1DBF
> *头部标识符* → _
> *头部标识符* → U+00A8U+00AAU+00ADU+00AFU+00B2U+00B5或者 U+00B7U+00BA
> *头部标识符* → U+00BCU+00BEU+00C0U+00D6U+00D8U+00F6或者 U+00F8U+00FF
> *头部标识符* → U+0100U+02FFU+0370U+167FU+1681U+180D或者 U+180FU+1DBF
> *头部标识符* → U+1E00U+1FFF
> *头部标识符* → U+200BU+200D, U+202AU+202E, U+203FU+2040, U+2054, or U+2060U+206F
> *头部标识符* → U+2070U+20CF, U+2100U+218F, U+2460U+24FF, or U+2776U+2793
> *头部标识符* → U+2C00U+2DFF or U+2E80U+2FFF
> *头部标识符* → U+3004U+3007, U+3021U+302F, U+3031U+303F, or U+3040U+D7FF
> *头部标识符* → U+F900U+FD3D, U+FD40U+FDCF, U+FDF0U+FE1F, or U+FE30U+FE44
> *头部标识符* → U+200BU+200DU+202AU+202EU+203FU+2040U+2054,或者 U+2060U+206F
> *头部标识符* → U+2070U+20CFU+2100U+218FU+2460U+24FF,或者 U+2776U+2793
> *头部标识符* → U+2C00U+2DFF 或者 U+2E80U+2FFF
> *头部标识符* → U+3004U+3007U+3021U+302FU+3031U+303F,或者 U+3040U+D7FF
> *头部标识符* → U+F900U+FD3DU+FD40U+FDCFU+FDF0U+FE1F,或者 U+FE30U+FE44
> *头部标识符* → U+FE47U+FFFD
> *头部标识符* → U+10000U+1FFFD, U+20000U+2FFFD, U+30000U+3FFFD, or U+40000U+4FFFD
> *头部标识符* → U+50000U+5FFFD, U+60000U+6FFFD, U+70000U+7FFFD, or U+80000U+8FFFD
> *头部标识符* → U+90000U+9FFFD, U+A0000U+AFFFD, U+B0000U+BFFFD, or U+C0000U+CFFFD
> *头部标识符* → U+D0000U+DFFFD or U+E0000U+EFFFD
> *头部标识符* → U+10000U+1FFFDU+20000U+2FFFDU+30000U+3FFFD,或者 U+40000U+4FFFD
> *头部标识符* → U+50000U+5FFFDU+60000U+6FFFDU+70000U+7FFFD,或者 U+80000U+8FFFD
> *头部标识符* → U+90000U+9FFFDU+A0000U+AFFFDU+B0000U+BFFFD,或者 U+C0000U+CFFFD
> *头部标识符* → U+D0000U+DFFFD 或者 U+E0000U+EFFFD
<a id="identifier_character"></a>
> *标识符字符* → 数值 0 - 9
> *标识符字符* → U+0300U+036F, U+1DC0U+1DFF, U+20D0U+20FF, or U+FE20U+FE2F
> *标识符字符* → U+0300U+036FU+1DC0U+1DFFU+20D0U+20FF,或者 U+FE20U+FE2F
> *标识符字符* → [*头部标识符*](#identifier_head)
<a id="identifier_characters"></a>
> *标识符字符组* → [*标识符字符*](#identifier_character) [*标识符字符列表*](#identifier_characters)<sub>可选</sub>
> *标识符字符组* → [*标识符字符*](#identifier_character) [*标识符字符*](#identifier_characters) <sub>可选</sub>
<a id="implicit_parameter_name"></a>
> *隐式参数名* → **$** [*十进制数字列表*](#decimal_digits)
<a id="keywords"></a>
## 关键字和符号
## 关键字和标点符号
下面这些被保留的关键字(*keywords*)不允许用作标识符,除非被反引号转义,具体描述请参考 [标识符](#identifiers)。
* **用在声明中的关键字:** *class**deinit*、*enum*、*extension*、*func*、*import*、*init*、*let*、*protocol*、*static*、*struct*、*subscript*、*typealias*、*var*
* **用在语句中的关键字:** *break**case*、*continue*、*default*、*do*、*else*、*fallthrough*、*if*、*in*、*for*、*return*、*switch*、*where*、*while*
* **用在表达式和类型中的关键字:** *as*、*dynamicType*、*is*、*new*、*super*、*self*、*Self*、*Type*、*\_\_COLUMN\_\_*、*\_\_FILE\_\_*、*\_\_FUNCTION\_\_*、*\_\_LINE\_\_*
* **用在模式中的关键字:** *\_*
* **特定上下文中被保留的关键字:** *associativity*、*didSet*、*get*、*infix*、*inout*、*left*、*mutating*、*none*、*nonmutating*、*operator*、*override*、*postfix*、*precedence*、*prefix*、*right*、*set*、*unowned*、*unowned(safe)*、*unowned(unsafe)*、*weak*、*willSet*,这些关键字在特定上下文之外可以被用标识符。
* 用在声明中的关键字:`class``deinit``enum``extension``func``import``init``inout``internal``let``operator``private``protocol``public``static``struct``subscript``typealias``var`
* 用在语句中的关键字:`break``case``continue``default``defer``do``else``fallthrough``for``guard``if``in``repeat``return``switch``where``while`
* 用在表达式和类型中的关键字:`as``catch``dynamicType``false``is``nil``rethrows``super``self``Self``throw``throws``true``try``__COLUMN__``__FILE__``__FUNCTION__``__LINE__`
* 用在模式中的关键字:`_`
* 特定上下文中被保留的关键字:`associativity``convenience``dynamic``didSet``final``get``infix``indirect``lazy``left``mutating``none``nonmutating``optional``override``postfix``precedence``prefix``Protocol``required``right``set``Type``unowned``weak``willSet`,这些关键字在特定上下文之外可以被用标识符。
以下标记被当作保留符号,不能用于自定义操作符:`(``)``{``}``[``]``.``,``:``;``=``@``#``&(作为前缀操作符)``->`、`` ``?``!(作为后缀操作符)`
以下符号被当作保留符号,不能用于自定义运算符:`(``)``{``}``[``]``.``,``:``;``=``@``#``&`(作为前缀运算符)`->`、`` ` ```?`、`!`(作为后缀运算符)
<a id="literals"></a>
## 字面量
@ -93,61 +100,83 @@ Swift 的“词法结构(*lexical structure*)”描述了能构成该语言
下面是字面量的一些示例:
```swift
42 // 整型字面量
3.14159 // 浮点型字面量
"Hello, world!" // 字符串型字面量
true // 布尔型字面量
42 // 整型字面量
3.14159 // 浮点型字面量
"Hello, world!" // 字符串型字面量
true // 布尔型字面量
```
字面量本身并不包含类型信息。事实上,一个字面量会被解析为拥有无限的精度,然后 Swift 的类型推导会尝试去推导出这个字面量的类型。比如,在 `let x: Int8 = 42` 这个声明中Swift 使用了显式类型标注(`: Int8`)来推导出 `42` 这个整型字面量的类型是 `Int8`。如果没有可用的类型信息, Swift 则会从标准库中定义的字面量类型中推导出一个默认的类型。整型字面量的默认类型是 `Int`,浮点型字面量的默认类型是 `Double`,字符串型字面量的默认类型是 `String`,布尔型字面量的默认类型是 `Bool`。比如,在 `let str = "Hello, world"` 这个声明中,字符串 `"Hello, world"`的默认推导类型就是 `String`
字面量本身并不包含类型信息。事实上,一个字面量会被解析为拥有无限的精度,然后 Swift 的类型推导会尝试去推导出这个字面量的类型。比如,在 `let x: Int8 = 42` 这个声明中Swift 使用了显式类型标注(`: Int8`)来推导出 `42` 这个整型字面量的类型是 `Int8`。如果没有可用的类型信息, Swift 则会从标准库中定义的字面量类型中推导出一个默认的类型。整型字面量的默认类型是 `Int`,浮点型字面量的默认类型是 `Double`,字符串型字面量的默认类型是 `String`,布尔型字面量的默认类型是 `Bool`。比如,在 `let str = "Hello, world"` 这个声明中,字符串 `"Hello, world"` 的默认推导类型就是 `String`。
当为一个字面量值指定了类型标注的时候,这个注的类型必须能通过这个字面量值实例化后得到。也就是说,这个类型必须遵守这些 Swift 标准库协议中的一个:整型字面量的`IntegerLiteralConvertible`协议、点型字面量的`FloatingPointLiteralConvertible`协议、字符串字面量的`StringLiteralConvertible`协议以及布尔型字面量的`BooleanLiteralConvertible`协议。比如,`Int8` 遵守了 `IntegerLiteralConvertible`协议,因此它能在 `let x: Int8 = 42` 这个声明中作为整型字面量 `42` 的类型标注。
当为一个字面量值指定了类型标注的时候,这个注的类型必须能通过这个字面量值实例化。也就是说,这个类型必须符合这些 Swift 标准库协议中的一个:整型字面量的 `IntegerLiteralConvertible` 协议、点型字面量的 `FloatingPointLiteralConvertible` 协议、字符串字面量的 `StringLiteralConvertible` 协议以及布尔型字面量的 `BooleanLiteralConvertible` 协议。比如,`Int8` 符合 `IntegerLiteralConvertible` 协议,因此它能在 `let x: Int8 = 42` 这个声明中作为整型字面量 `42` 的类型标注。
> 字面量语法
> *字面量* → [*数字型字面量*](#numeric_literal) | [*字符串型字面量*](#string_literal) | [*布尔型字面量*](#boolean_literal) | [*nil型字面量*](#nil_literal)
<a id="numeric_literal"></a>
> *数字型字面量* → -<sub>可选</sub>[*整型字面量*](#integer_literal) | -<sub>可选</sub>[*点型字面量*](#floating_point_literal)
> *数字型字面量* → **-** <sub>可选</sub> [*整型字面量*](#integer_literal) | **-** <sub>可选</sub> [*点型字面量*](#floating_point_literal)
<a id="boolean_literal"></a>
> *布尔型字面量* → **true** | **false**
<a id="nil_literal"></a>
> *nil型字面量* → **nil**
### 整型字面量
整型字面量(*integer literals*)表示未指定精度整型数的值。整型字面量默认用十进制表示,可以加前缀来指定其他的进制,二进制字面量加 `0b`,八进制字面量加 `0o`,十六进制字面量加 `0x`。
十进制字面量包含数字 `0``9`。二进制字面量只包含 `0``1`,八进制字面量包含数字 `0``7`,十六进制字面量包含数字 `0``9` 以及字母 `A``F` (大小写均可)。
十进制字面量包含数字 `0` 至 `9`。二进制字面量只包含 `0` 或 `1`,八进制字面量包含数字 `0` 至 `7`,十六进制字面量包含数字 `0` 至 `9` 以及字母 `A` 至 `F`(大小写均可)。
负整数的字面量在整型字面量前加`-`,比如 `-42`
负整数的字面量在整型字面量前加号 `-`,比如 `-42`。
整型字面面可以使用下划线 `_` 来增加数字的可读性,下划线会被系统忽略,因此不会影响字面量的值。同样地,也可以在数字前加 `0`,并不会影响字面量的值。
除非特别指定,整型字面量的默认推导类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数类型](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID323)。
> 整型字面量语法
<a id="integer_literal"></a>
> *整型字面量* → [*二进制字面量*](#binary_literal)
> *整型字面量* → [*八进制字面量*](#octal_literal)
> *整型字面量* → [*十进制字面量*](#decimal_literal)
> *整型字面量* → [*十六进制字面量*](#hexadecimal_literal)
<a id="binary_literal"></a>
> *二进制字面量* → **0b** [*二进制数字*](#binary_digit) [*二进制字面量字符组*](#binary_literal_characters)<sub>可选</sub>
> *二进制字面量* → **0b** [*二进制数字*](#binary_digit) [*二进制字面量字符组*](#binary_literal_characters) <sub>可选</sub> <a id="binary_digit"></a>
> *二进制数字* → 数值 0 到 1
<a id="binary_literal_character"></a>
> *二进制字面量字符* → [*二进制数字*](#binary_digit) | _
> *二进制字面量字符组* → [*二进制字面量字符*](#binary_literal_character) [*二进制字面量字符组*](#binary_literal_characters)<sub>可选</sub>
<a id="binary_literal_characters"></a>
> *二进制字面量字符组* → [*二进制字面量字符*](#binary_literal_character) [*二进制字面量字符组*](#binary_literal_characters) <sub>可选</sub>
<a id="octal_literal"></a>
> *八进制字面量* → **0o** [*八进字数字*](#octal_digit) [*八进制字符列表*](#octal_literal_characters)<sub>可选</sub>
> *八进制字面量* → **0o** [*八进字数字*](#octal_digit) [*八进制字符*](#octal_literal_characters) <sub>可选</sub>
<a id="octal_digit"></a>
> *八进字数字* → 数值 0 到 7
<a id="octal_literal_character"></a>
> *八进制字符* → [*八进字数字*](#octal_digit) | _
> *八进制字符组* → [*八进制字符*](#octal_literal_character) [*八进制字符列表*](#octal_literal_characters)<sub>可选</sub>
<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_digit"></a>
> *十进制数字* → 数值 0 到 9
> *十进制数字列表* → [*十进制数字*](#decimal_digit) [*十进制数字列表*](#decimal_digits)<sub>可选</sub>
> *十进制字符* → [*十进制数字*](#decimal_digit) | _
> *十进制字符列表* → [*十进制字符*](#decimal_literal_character) [*十进制字符列表*](#decimal_literal_characters)<sub>可选</sub>
<a id="decimal_digits"></a>
> *十进制数字组* → [*十进制数字*](#decimal_digit) [*十进制数字组*](#decimal_digits) <sub>可选</sub>
<a id="decimal_literal_character"></a>
> *十进制字符* → [*十进制数字*](#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>
> *十六进制字面量* → **0x** [*十六进制数字*](#hexadecimal_digit) [*十六进制字面量字符*](#hexadecimal_literal_characters) <sub>可选</sub>
<a id="hexadecimal_digit"></a>
> *十六进制数字* → 数值 0 到 9, 字母 a 到 f, 或 A 到 F
<a id="hexadecimal_literal_character"></a>
> *十六进制字符* → [*十六进制数字*](#hexadecimal_digit) | _
> *十六进制字面量字符列表* → [*十六进制字符*](#hexadecimal_literal_character) [*十六进制字面量字符列表*](#hexadecimal_literal_characters)<sub>可选</sub>
<a id="hexadecimal_literal_characters"></a>
> *十六进制字面量字符组* → [*十六进制字符*](#hexadecimal_literal_character) [*十六进制字面量字符组*](#hexadecimal_literal_characters) <sub>可选</sub>
### 浮点型字面量
@ -155,118 +184,145 @@ true // 布尔型字面量
浮点型字面量默认用十进制表示(无前缀),也可以用十六进制表示(加前缀 `0x`)。
十进制浮点型字面量*decimal floating-point literals*由十进制数字串后跟小数部分或指数部分(或两者皆有)组成。十进制小数部分由小数点 `.` 后跟十进制数字串组成。指数部分由大写或小写字母 `e` 为前缀后跟十进制数字串组成,这串数字表示 `e` 之前的数量乘以 10 的几次方。例如:`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `125.0`;同样,`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `0.0125`
十进制浮点型字面量由十进制数字串后跟小数部分或指数部分(或两者皆有)组成。十进制小数部分由小数点 `.` 后跟十进制数字串组成。指数部分由大写或小写字母 `e` 为前缀后跟十进制数字串组成,这串数字表示 `e` 之前的数量乘以 10 的几次方。例如:`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `125.0`;同样,`1.25e2` 表示 `1.25 ⨉ 10^2`,也就是 `0.0125`。
十六进制浮点型字面量*hexadecimal floating-point literals*)由前缀 `0x` 后跟可选的十六进制小数部分以及十六进制指数部分组成。十六进制小数部分由小数点后跟十六进制数字串组成。指数部分由大写或小写字母 `p` 为前缀后跟十进制数字串组成,这串数字表示 `p` 之前的数量乘以 2 的几次方。例如:`0xFp2` 表示 `15 ⨉ 2^2`,也就是 `60`;同样,`0xFp-2` 表示 `15 ⨉ 2^-2`,也就是 `3.75`
十六进制浮点型字面量由前缀 `0x` 后跟可选的十六进制小数部分以及十六进制指数部分组成。十六进制小数部分由小数点后跟十六进制数字串组成。指数部分由大写或小写字母 `p` 为前缀后跟十进制数字串组成,这串数字表示 `p` 之前的数量乘以 2 的几次方。例如:`0xFp2` 表示 `15 ⨉ 2^2`,也就是 `60`;同样,`0xFp-2` 表示 `15 ⨉ 2^-2`,也就是 `3.75`。
的浮点型字面量由一元运算符减号 `-` 和浮点型字面量组成,例如 `-42.5`
负数的浮点型字面量由负号 `-` 和浮点型字面量组成,例如 `-42.5`。
浮点型字面量允许使用下划线 `_` 来增强数字的可读性,下划线会被系统忽略,因此不会影响字面量的值。同样地,也可以在数字前加 `0`,并不会影响字面量的值。
除非特别指定,浮点型字面量的默认推导类型为 Swift 标准库类型中的 `Double`表示64位浮点数。Swift 标准库也定义了 `Float` 类型表示32位浮点数。
除非特别指定,浮点型字面量的默认推导类型为 Swift 标准库类型中的 `Double`,表示 64 位浮点数。Swift 标准库也定义了 `Float` 类型,表示 32 位浮点数。
> 浮点型字面量语法
> *浮点数字面量* → [*十进制字面量*](#decimal_literal) [*十进制分数*](#decimal_fraction)<sub>可选</sub> [*十进制指数*](#decimal_exponent)<sub>可选</sub>
> *浮点数字面量* → [*十六进制字面量*](#hexadecimal_literal) [*十六进制分数*](#hexadecimal_fraction)<sub>可选</sub> [*十六进制指数*](#hexadecimal_exponent)
<a id="decimal_fraction"></a>
> *十进制分数* → **.** [*十进制字面量*](#decimal_literal)
> *十进制指数* → [*浮点数e*](#floating_point_e) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal_literal)
<a id="hexadecimal_literal"></a>
> *十六进制分数* → **.** [*十六进制数字*](#hexadecimal_digit) [*十六进制字面量字符列表*](#hexadecimal_literal_characters)<sub>可选</sub>
> *十六进制指数* → [*浮点数p*](#floating_point_p) [*正负号*](#sign)<sub>可选</sub> [*十进制字面量*](#decimal_literal)
<a id="floating_point_e"></a>
> *浮点数e* → **e** | **E**
> *浮点数p* → **p** | **P**
> *正负号* → **+** | **-**
<a id="floating_point_literal"></a>
> *浮点数字面量* → [*十进制字面量*](#decimal_literal) [*十进制分数*](#decimal_fraction) <sub>可选</sub> [*十进制指数*](#decimal_exponent) <sub>可选</sub>
> *浮点数字面量* → [*十六进制字面量*](#hexadecimal_literal) [*十六进制分数*](#hexadecimal_fraction) <sub>可选</sub> [*十六进制指数*](#hexadecimal_exponent)
<a id="decimal_fraction"></a>
> *十进制分数* → **.** [*十进制字面量*](#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>
<a id="hexadecimal_exponent"></a>
> *十六进制指数* → [*十六进制指数 p*](#floating_point_p) [*正负号*](#sign) <sub>可选</sub> [*十进制字面量*](#decimal_literal)
<a id="floating_point_e"></a>
> *十进制指数 e* → **e** | **E**
<a id="floating_point_p"></a>
> *十六进制指数 p* → **p** | **P**
<a id="sign"></a>
> *正负号* → **+** | **-**
### 字符串型字面量
字符串型字面量(*string literal*)由被包在双引号中的一串字符组成,形式如下:
```
```swift
"characters"
```
字符串型字面量中不能包含未转义的双引号 `"`)、未转义的反斜线(`\`)、回车符*carriage return*)或换行符(*line feed*
字符串型字面量中不能包含未转义的双引号`"`)、未转义的反斜线(`\`)、回车符、换行符
可以在字符串字面量中使用的转义特殊符号如下:
* 空字符Null Character`\0`
* 反斜线Backslash`\\`
* 水平制表符Horizontal Tab`\t`
* 换行符Line Feed`\n`
* 回车符Carriage Return`\r`
* 双引号Double Quote`\"`
* 单引号Single Quote`\'`
* Unicode标量 `\u{n}`n为一到八位的十六进制数字
* 空字符 `\0`
* 反斜线 `\\`
* 水平制表符 `\t`
* 换行符 `\n`
* 回车符 `\r`
* 双引号 `\"`
* 单引号 `\'`
* Unicode 标量 `\u{`n`}`n 为一到八位的十六进制数字
字符串字面量允许在反斜杠括号 `\()` 中插入表达式的值。插入表达式*interpolated expression*不能包含未转义的双引号 `"`、未转义的反斜线 `\`、回车符或者换行符。表达式结果的类型必须在 *String* 类中有对应的初始化方法。
字符串字面量允许在反斜杠 `\` 后的括号 `()` 中插入表达式的值。插入表达式可以包含字符串字面量,但不能包含未转义的双引号 `"`、未转义的反斜线 `\`、回车符换行符。
例如,以下所有字符串字面量的值都是相同的:
```
```swift
"1 2 3"
"1 2 \("3")"
"1 2 \(3)"
"1 2 \(1 + 2)"
let x = 3; "1 2 \(x)"
```
字符串字面量的默认推导类型为 `String`组成字符串的字符默认推导类型为 `Character`。更多有关 `String``Character` 的信息请参 [字符串和字符](../chapter2/03_Strings_and_Characters.html) 以及[字符串结构参考](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_String_Structure/index.html#//apple_ref/doc/uid/TP40015181)。
字符串字面量的默认推导类型为 `String`更多有关 `String` 类型的信息请参 [字符串和字符](../chapter2/03_Strings_and_Characters.html) 以及 [字符串结构参考](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_String_Structure/index.html#//apple_ref/doc/uid/TP40015181)。
`` 操作符连接的字符型字面量是在编译时进行连接的。比如下面的 `textA``textB` 完全一样的—— `textA` 没有任何运行时的连接操作。
`` 操作符连接的字符型字面量是在编译时进行连接的。比如下面的 `textA``textB` 完全一样的`textA` 没有任何运行时的连接操作。
```
```swift
let textA = "Hello " + "world"
let textB = "Hello world"
```
> 字符型字面量语法
> *字符串字面量* → **"** [*引用文本*](#quoted_text)<sub>可选</sub> **"**
<a id="quoted_text"></a>
> *引用文本* → [*引用文本条目*](#quoted_text_item) [*引用文本*](#quoted_text) <sub>可选</sub>
> *引用文本条目* → [*转义字符*](#escaped_character)
> *引用文本条目* → **\(** [*表达式*](./04_Expressions.html) **)**
> *引用文本条目* → **除了"­, \­, U+000A, 或者 U+000D的所有Unicode的字符**
> *转义字符* → **\0** | **\\** | **\t** | **\n** | **\r** | **\"** | **\'**
> *转义字符* → **\u {** [*unicode标量数字*](#unicode_scalar_digits) **}**
> *unicode标量数字* → 一到八位的十六进制数字
> 字符型字面量语法
<a id="string_literal"></a>
> *字符串字面量* → [*静态字符串字面量*](#static_string_literal) | [*插值字符串字面量*](#interpolated_string_literal)
<a id="static_string_literal"></a>
> *静态字符串字面量* → **"**[*引用文本*](#quoted_text) <sub>可选</sub>**"**
<a id="quoted_text"></a>
> *引用文本* → [*引用文本项*](#quoted_text_item) [*引用文本*](#quoted_text) <sub>可选</sub>
<a id="quoted_text_item"></a>
> *引用文本项* → [*转义字符*](#escaped_character)
> *引用文本项* → 除了 **"**、**\\**、U+000A、U+000D 以外的所有 Unicode 字符
<a id="interpolated_string_literal"></a>
> *插值字符串字面量* → **"**[*插值文本*](#interpolated_text) <sub>可选</sub>**"**
<a id="interpolated_text"></a>
> *插值文本* → [*插值文本项*](#interpolated_text_item) [*插值文本*](#interpolated_text) <sub>可选</sub>
<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) **}**
<a id="unicode_scalar_digits"></a>
> *unicode 标量数字* → 一到八位的十六进制数字
<a id="operators"></a>
## 运算符
Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基础运算符](../chapter2/02_Basic_Operators.html) 和 [高级运算符](../chapter2/25_Advanced_Operators.html) 中进行了阐述。这一小节将描述哪些字符能用于自定义运算符。
自定义运算符可以由以下其中之一的 ASCII 字符 `/``=``-``+``!``*``%``<``>``&``|``^``?` 以及 `~`, 或者后面语法中规定的任一个 Unicode 字符开始。在第一个字符之后,允许使用组合型 Unicode 字符。也可以使用两个或者多个的点号来自定义运算符(比如, `....`)。虽然可以自定义包含问号`?`的运算符,但是这个运算符不能只包含单独的一个问号。
自定义运算符可以由以下其中之一的 ASCII 字符 `/``=``-``+``!``*``%``<``>``&``|``^``?` 以及 `~`或者后面语法中规定的任一个 Unicode 字符开始。在第一个字符之后,允许使用组合型 Unicode 字符。也可以使用两个或者多个的点号来自定义运算符(比如`....`)。虽然可以自定义包含问号 `?` 的运算符,但是这个运算符不能只包含单独的一个问号。
注意:
以下这些标记 =, ->, //, /*, */, ., <(前缀运算符), &, and ?, ?(中缀运算符), >(后缀运算符), ! 以及 ? 是被系统保留的。这些标记不能被重载,也不能用于自定义操作符。
> 注意
以下这些标记 `=``->``//``/*``*/``.``<`(前缀运算符)、`&``?``?`(中缀运算符)`>`(后缀运算符)`!``?` 是被系统保留的。这些符号不能被重载,也不能用于自定义运算符。
运算符两侧的空白被用来区分该运算符是否为前缀运算符*prefix operator*)、后缀运算符(*postfix operator*)或二元运算符(*binary operator*。规则总结如下:
运算符两侧的空白被用来区分该运算符是否为前缀运算符、后缀运算符或二元运算符。规则总结如下:
* 如果运算符两侧都有空白或两侧都无空白,将被看作二元运算符。例如:`a+b``a + b` 中的运算符 `+` 被看作二元运算符。
* 如果运算符只有左侧空白,将被看作前缀一元运算符。例如 `a ++b` 中的 `++` 被看作前缀一元运算符。
* 如果运算符只有右侧空白,将被看作后缀一元运算符。例如 `a++ b` 中的 `++` 被看作后缀一元运算符。
* 如果运算符左侧没有空白并紧跟 `.`,将被看作后缀一元运算符。例如 `a++.b` 中的 `++` 被看作后缀一元运算符(即上式被视为 `a++ .b` 而非 `a ++ .b`)。
鉴于这些规则,运算符前的字符 `(``[``{` 运算符后的字符 `)``]``}` 以及字符 `,``;``:` 都被视为空白。
鉴于这些规则,运算符前的字符 `(``[``{`运算符后的字符 `)``]``}`以及字符 `,``;``:` 都被视为空白。
以上规则需注意一点,如果预定义运算符 `!``?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选链*optional-chaining*)操作符,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
以上规则需注意一点,如果预定义运算符 `!``?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选链式调用运算符,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
在某些特定的构造中 ,以 `<``>` 开头的运算符会被分离成两个或多个标记,剩余部分以同样的方式被再次分离。因此,在 `Dictionary<String, Array<Int>>` 中没有必要添加空白来消除闭合字符 `>` 的歧义。在这个例子中, 闭合字符 `>` 不会被视为单独的标记,因而不会被误解析为 `>>` 运算符的一部分
在某些特定的设计中 ,以 `<``>` 开头的运算符会被分离成两个或多个符号,剩余部分可能会以同样的方式被再次分离。因此,在 `Dictionary<String, Array<Int>>` 中没有必要添加空白来消除闭合字符 `>` 的歧义。在这个例子中, 闭合字符 `>` 不会被视为单独的符号,因而不会被误解析为 `>>` 运算符。
要学习如何自定义运算符,请参考 [自定义操作](../chapter2/25_Advanced_Operators.html#custom_operators) 和 [运算符声明](./05_Declarations.html#operator_declaration)。要学习如何重载运算符,请参考 [运算符方法](../chapter2/25_Advanced_Operators.html#operator_functions)。
要学习如何自定义运算符,请参考 [自定义运算](../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+00A1U+00A7
> *头部运算符* → U+00A9 or U+00AB
> *头部运算符* → U+00AC or U+00AE
> *头部运算符* → U+00B0U+00B1, U+00B6, U+00BB, U+00BF, U+00D7, or U+00F7
> *头部运算符* → U+2016U+2017 or U+2020U+2027
> *头部运算符* → U+00A9 U+00AB
> *头部运算符* → U+00AC U+00AE
> *头部运算符* → U+00B0U+00B1U+00B6U+00BBU+00BFU+00D7,或 U+00F7
> *头部运算符* → U+2016U+2017 U+2020U+2027
> *头部运算符* → U+2030U+203E
> *头部运算符* → U+2041U+2053
> *头部运算符* → U+2055U+205E
@ -276,6 +332,7 @@ Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基
> *头部运算符* → U+2E00U+2E7F
> *头部运算符* → U+3001U+3003
> *头部运算符* → U+3008U+3030
<a id="operator_character"></a>
> *运算符字符* → [*头部运算符*](#operator_head)
> *运算符字符* → U+0300U+036F
@ -283,13 +340,16 @@ Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基
> *运算符字符* → U+20D0U+20FF
> *运算符字符* → U+FE00U+FE0F
> *运算符字符* → U+FE20U+FE2F
> *运算符字符* → U+E0100U+E01EF
<a id="operator_characters"></a>
> *运算符字符组* → [*运算符字符*](#operator_character) [*运算符字符组*] (#operator_characters)<sub>可选</sub>
> *运算符字符* → U+E0100U+E01EF
<a id="operator_characters"></a>
> *运算符字符组* → [*运算符字符*](#operator_character) [*运算符字符组*](#operator_characters) <sub>可选</sub>
<a id="dot_operator_head"></a>
> *头部点运算符* → **..**
> *头部点运算符字符* → . | [*运算符字符*](#operator_character)
> *头部点运算符字符* → [*点运算符字符*](#dot_operator_character) [*运算符字符*](#dot_operator_characters)<sub>可选</sub>
<a id="dot_operator_character"></a>
> *点运算符字符* → **.** | [*运算符字符*](#operator_character)
<a id="dot_operator_characters"></a>
> *点运算符字符组* → [*点运算符字符*](#dot_operator_character) [*点运算符字符组*](#dot_operator_characters) <sub>可选</sub>
> *二元运算符* → [*运算符*](#operator)
> *前置运算符* → [*运算符*](#operator)