ver 1.0
This commit is contained in:
@ -1,12 +1,22 @@
|
||||
> 翻译:ChildhoodAndy
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
|
||||
# 关于语言附注
|
||||
-----------------
|
||||
|
||||
本页内容包括:
|
||||
|
||||
- [如何阅读语法](#how_to_read_the_grammar)
|
||||
|
||||
本书的这一节描述了Swift编程语言的形式语法。这里描述的语法是为了帮助您更详细的了解该语言,而不是让您直接实现一个解析器或编译器。
|
||||
|
||||
|
||||
Swift语言相对小点,这是由于在Swift代码中几乎无处不在的许多常见的的类型,函数以及运算符都由Swift标准库来定义。虽然这些类型,函数和运算符不是Swift语言本身的一部分,但是它们被广泛用于这本书的讨论和代码范例。
|
||||
|
||||
# 如何阅读语法
|
||||
<a name="how_to_read_the_grammar"></a>
|
||||
## 如何阅读语法
|
||||
|
||||
用来描述Swift编程语言形式语法的记法遵循下面几个约定:
|
||||
|
||||
@ -31,9 +41,3 @@ Swift语言相对小点,这是由于在Swift代码中几乎无处不在的许
|
||||
> getter-setter-block → { [*getter-clause*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/getter-clause) [*setter-clause*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/setter-clause)*opt* }
|
||||
|
||||
> getter-setter-block → { [*setter-clause*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/setter-clause) [*getter-clause*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/getter-clause)}
|
||||
|
||||
|
||||
================================================================
|
||||
上篇:[高级操作符]()
|
||||
|
||||
下篇:[词法结构]()
|
||||
@ -1,24 +1,30 @@
|
||||
# 语法结构
|
||||
> 翻译:superkam
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 词法结构
|
||||
-----------------
|
||||
|
||||
本页包含内容:
|
||||
|
||||
- 空白与注释(*Whitespace and Comments*)
|
||||
- 标识符(*Identifiers*)
|
||||
- 关键字(*Keywords*)
|
||||
- 字面量(*Literals*)
|
||||
- 运算符(*Operators*)
|
||||
- [空白与注释(*Whitespace and Comments*)](#whitespace_and_comments)
|
||||
- [标识符(*Identifiers*)](#identifiers)
|
||||
- [关键字(*Keywords*)](#keywords)
|
||||
- [字面量(*Literals*)](#literals)
|
||||
- [运算符(*Operators*)](#operators)
|
||||
|
||||
Swift 的“语法结构(*lexical structure*)”描述了如何在该语言中用字符序列构建合法标记,组成该语言中最底层的代码块,并在之后的章节中用于描述语言的其他部分。
|
||||
Swift 的“词法结构(*lexical structure*)”描述了如何在该语言中用字符序列构建合法标记,组成该语言中最底层的代码块,并在之后的章节中用于描述语言的其他部分。
|
||||
|
||||
通常,标记在随后介绍的语法约束下,由 Swift 源文件的输入文本中提取可能的最长子串生成。这种方法称为“最长匹配项(*longest match*)”,或者“最大适合”(*maximal munch*)。
|
||||
|
||||
<a name="whitespace_and_comments"></a>
|
||||
## 空白与注释
|
||||
|
||||
空白(*whitespace*)有两个用途:分隔源文件中的标记和区分运算符属于前缀还是后缀,(参见 [运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-XID_871))在其他情况下则会被忽略。以下的字符会被当作空白:空格(*space*)(U+0020)、换行符(*line feed*)(U+000A)、回车符(*carriage return*)(U+000D)、水平 tab(*horizontal tab*)(U+0009)、垂直 tab(*vertical tab*)(U+000B)、换页符(*form feed*)(U+000C)以及空(*null*)(U+0000)。
|
||||
|
||||
注释(*comments*)被编译器当作空白处理。单行注释由 `//` 开始直到该行结束。多行注释由 `/*` 开始,以 `*/` 结束。可以嵌套注释,但注意注释标记必须匹配。
|
||||
|
||||
<a name="identifiers"></a>
|
||||
## 标识符
|
||||
|
||||
标识符(*identifiers*)可以由以下的字符开始:大写或小写的字母 `A` 到 `Z`、下划线 `_`、基本多语言面(*Basic Multilingual Plane*)中的 Unicode 非组合字符以及基本多语言面以外的非专用区(*Private Use Area*)字符。首字符之后,标识符允许使用数字和 Unicode 字符组合。
|
||||
@ -28,60 +34,61 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
闭包(*closure*)中如果没有明确指定参数名称,参数将被隐式命名为 <code>$0</code>、<code>$1</code>、<code>$2</code>... 这些命名在闭包作用域内是合法的标识符。
|
||||
|
||||
> 标识符语法
|
||||
>
|
||||
>
|
||||
> *identifier* → [identifier-head](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-head) [identifier-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *identifier* → \` [identifier-head](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-head) [identifier-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-characters) *opt* \`
|
||||
>
|
||||
>
|
||||
> *identifier* → [implicit-parameter-name](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/implicit-parameter-name)
|
||||
>
|
||||
>
|
||||
> *identifier-list* → [identifier](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier) | [identifier](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier) , [identifier-list](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-list)
|
||||
>
|
||||
>
|
||||
> *identifier-head* → A 到 Z 大写或小写字母
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+00A8, U+00AA, U+00AD, U+00AF, U+00B2–U+00B5, 或 U+00B7–U+00BA
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+00BC–U+00BE, U+00C0–U+00D6, U+00D8–U+00F6, 或 U+00F8–U+00FF
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+0100–U+02FF, U+0370–U+167F, U+1681–U+180D, 或 U+180F–U+1DBF
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+1E00–U+1FFF
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+200B–U+200D, U+202A–U+202E, U+203F–U+2040, U+2054, 或 U+2060–U+206F
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+2070–U+20CF, U+2100–U+218F, U+2460–U+24FF, 或 U+2776–U+2793
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+2C00–U+2DFF 或 U+2E80–U+2FFF
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+3004–U+3007, U+3021–U+302F, U+3031–U+303F, 或 U+3040–U+D7FF
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+F900–U+FD3D, U+FD40–U+FDCF, U+FDF0–U+FE1F, 或 U+FE30–U+FE44
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+FE47–U+FFFD
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+10000–U+1FFFD, U+20000–U+2FFFD, U+30000–U+3FFFD, 或 U+40000–U+4FFFD
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+50000–U+5FFFD, U+60000–U+6FFFD, U+70000–U+7FFFD, 或 U+80000–U+8FFFD
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+90000–U+9FFFD, U+A0000–U+AFFFD, U+B0000–U+BFFFD, 或 U+C0000–U+CFFFD
|
||||
>
|
||||
>
|
||||
> *identifier-head* → U+D0000–U+DFFFD 或 U+E0000–U+EFFFD
|
||||
>
|
||||
>
|
||||
> *identifier-character* → 数字 0 到 9
|
||||
>
|
||||
>
|
||||
> *identifier-character* → U+0300–U+036F, U+1DC0–U+1DFF, U+20D0–U+20FF, or U+FE20–U+FE2F
|
||||
>
|
||||
>
|
||||
> *identifier-character* → [identifier-head](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-head)
|
||||
>
|
||||
>
|
||||
> *identifier-characters* → [identifier-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-character) [identifier-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *implicit-parameter-name* → **$** [decimal-digits](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-digits)
|
||||
|
||||
<a name="keywords"></a>
|
||||
## 关键字
|
||||
|
||||
被保留的关键字(*keywords*)不允许用作标识符,除非被反引号转义,参见 [标识符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-XID_796)。
|
||||
|
||||
* **用作声明的关键字:** *class*、*deinit*、*enum*、*extension*、*func*、*import*、*init*、*let*、*protocol*、*static*、*struct*、*subscript*、*typealias*、*var*
|
||||
* **用作声明的关键字:** *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*
|
||||
|
||||
@ -89,6 +96,7 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
|
||||
* **特定上下文中被保留的关键字:** *associativity*、*didSet*、*get*、*infix*、*inout*、*left*、*mutating*、*none*、*nonmutating*、*operator*、*override*、*postfix*、*precedence*、*prefix*、*right*、*set*、*unowned*、*unowned(safe)*、*unowned(unsafe)*、*weak*、*willSet*,这些关键字在特定上下文之外可以被用于标识符。
|
||||
|
||||
<a name="literals"></a>
|
||||
## 字面量
|
||||
|
||||
字面值表示整型、浮点型数字或文本类型的值,举例如下:
|
||||
@ -98,7 +106,7 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
"Hello, world!" // 文本型字面量
|
||||
|
||||
> 字面量语法
|
||||
>
|
||||
>
|
||||
> *literal* → [integer-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/integer-literal) | [floating-point-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/floating-point-literal) | [string-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/string-literal)
|
||||
|
||||
### 整型字面量
|
||||
@ -117,47 +125,47 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
除非特殊指定,整型字面量的默认类型为 Swift 标准库类型中的 `Int`。Swift 标准库还定义了其他不同长度以及是否带符号的整数类型,请参考 [整数类型](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_411)。
|
||||
|
||||
> 整型字面量语法
|
||||
>
|
||||
>
|
||||
> *integer-literal* → [binary-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-literal)
|
||||
>
|
||||
>
|
||||
> *integer-literal* → [octal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-literal)
|
||||
>
|
||||
>
|
||||
> *integer-literal* → [decimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal)
|
||||
>
|
||||
>
|
||||
> *integer-literal* → [hexadecimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal)
|
||||
>
|
||||
>
|
||||
> *binary-literal* → **0b** [binary-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-digit) [binary-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *binary-digit* → 数字 0 或 1
|
||||
>
|
||||
>
|
||||
> *binary-literal-character* → [binary-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-digit) | _
|
||||
>
|
||||
>
|
||||
> *binary-literal-characters* → [binary-literal-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-literal-character) [binary-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/binary-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *octal-literal* → **0o** [octal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-digit) [octal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *octal-digit* → 数字 0 至 7
|
||||
>
|
||||
>
|
||||
> *octal-literal-character* → [octal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-digit) | _
|
||||
>
|
||||
>
|
||||
> *octal-literal-characters* → [octal-literal-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-literal-character) [octal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/octal-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *decimal-literal* → [decimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-digit) [decimal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *decimal-digit* → 数字 0 至 9
|
||||
>
|
||||
>
|
||||
> *decimal-digits* → [decimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-digit) [decimal-digits](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-digits) *opt*
|
||||
>
|
||||
>
|
||||
> *decimal-literal-character* → [decimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-digit) | _
|
||||
>
|
||||
>
|
||||
> *decimal-literal-characters* → [decimal-literal-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal-character) [decimal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *hexadecimal-literal* → **0x** [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal-characters) *opt*
|
||||
>
|
||||
>
|
||||
> *hexadecimal-digit* → 数字 0 到 9, a 到 f, 或 A 到 F
|
||||
>
|
||||
>
|
||||
> *hexadecimal-literal-character* → [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) | _
|
||||
>
|
||||
>
|
||||
> *hexadecimal-literal-characters* → [hexadecimal-literal-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal-character) [hexadecimal-literal-characters](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal-characters) *opt*
|
||||
|
||||
### 浮点型字面量
|
||||
@ -176,27 +184,27 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
|
||||
10_000.56 // 等于 10000.56
|
||||
005000.76 // 等于 5000.76
|
||||
|
||||
|
||||
除非特殊指定,浮点型字面量的默认类型为 Swift 标准库类型中的 `Double`,表示64位浮点数。Swift 标准库也定义 `Float` 类型,表示32位浮点数。
|
||||
|
||||
> 浮点型字面量语法
|
||||
>
|
||||
>
|
||||
> *floating-point-literal* → [decimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal) [decimal-fraction](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-fraction) *opt* [decimal-exponent](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-exponent) *opt*
|
||||
>
|
||||
>
|
||||
> *floating-point-literal* → [hexadecimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal) [hexadecimal-fraction](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-fraction) *opt* [hexadecimal-exponent](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-exponent)
|
||||
>
|
||||
>
|
||||
> *decimal-fraction* → . [decimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal)
|
||||
>
|
||||
>
|
||||
> *decimal-exponent* → [floating-point-e](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/floating-point-e) [sign](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/sign) *opt* [decimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/decimal-literal)
|
||||
>
|
||||
>
|
||||
> *hexadecimal-fraction* → . [hexadecimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal) *opt*
|
||||
>
|
||||
>
|
||||
> *hexadecimal-exponent* → [floating-point-p](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/floating-point-p) [sign](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/sign) *opt* [hexadecimal-literal](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-literal)
|
||||
>
|
||||
>
|
||||
> *floating-point-e* → **e** | **E**
|
||||
>
|
||||
>
|
||||
> *floating-point-p* → **p** | **P**
|
||||
>
|
||||
>
|
||||
> *sign* → **+** | **-**
|
||||
|
||||
|
||||
@ -235,29 +243,30 @@ Swift 的“语法结构(*lexical structure*)”描述了如何在该语言
|
||||
"1 2 \(3)"
|
||||
"1 2 \(1 + 2)"
|
||||
var x = 3; "1 2 \(x)"
|
||||
|
||||
|
||||
文本型字面量的默认类型为 `String`。组成字符串的字符类型为 `Character`。更多有关 `String` 和 `Character` 的信息请参照 [字符串和字符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-XID_368)。
|
||||
|
||||
> 文本型字面量语法
|
||||
>
|
||||
>
|
||||
> *string-literal* → **"** [quoted-text](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/quoted-text) **"**
|
||||
>
|
||||
>
|
||||
> *quoted-text* → [quoted-text-item](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/quoted-text-item) [quoted-text](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/quoted-text) *opt*
|
||||
>
|
||||
>
|
||||
> *quoted-text-item* → [escaped-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/escaped-character)
|
||||
>
|
||||
>
|
||||
> *quoted-text-item* → **\(** [expression](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression) **)**
|
||||
>
|
||||
>
|
||||
> *quoted-text-item* → 除 `"`、`\`、`U+000A` 或 `U+000D` 以外的任何 Unicode 扩展字符集
|
||||
>
|
||||
>
|
||||
> *escaped-character* → **\0** | **\\** | **\t** | **\n** | **\r** | **\"** | **\'**
|
||||
>
|
||||
>
|
||||
> *escaped-character* → **\x** [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit)
|
||||
>
|
||||
>
|
||||
> *escaped-character* → **\u** [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit)
|
||||
>
|
||||
>
|
||||
> *escaped-character* → **\U** [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit) [hexadecimal-digit](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/hexadecimal-digit)
|
||||
|
||||
<a name="operators"></a>
|
||||
## 运算符
|
||||
|
||||
Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基础运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_70) 和 [高级运算符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_28) 中进行了阐述。这里将描述哪些字符能用作运算符。
|
||||
@ -277,20 +286,20 @@ Swift 标准库定义了许多可供使用的运算符,其中大部分在 [基
|
||||
|
||||
鉴于这些规则,运算符前的字符 `(`、`[` 和 `{` ;运算符后的字符 `)`、`]` 和 `}` 以及字符 `,`、`;` 和 `:` 都将用于空白检测。
|
||||
|
||||
以上规则需注意一点,如果运算符 `!` 或 `?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选类型(*optional type*)修饰,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
|
||||
以上规则需注意一点,如果运算符 `!` 或 `?` 左侧没有空白,则不管右侧是否有空白都将被看作后缀运算符。如果将 `?` 用作可选类型(*optional type*)修饰,左侧必须无空白。如果用于条件运算符 `? :`,必须两侧都有空白。
|
||||
|
||||
在特定构成中 ,以 `<` 或 `>` 开头的运算符会被分离成两个或多个标记,剩余部分以同样的方式会被再次分离。因此,在 `Dictionary<String, Array<Int>>` 中没有必要添加空白来消除闭合字符 `>` 的歧义。在这个例子中, 闭合字符 `>` 被看作单字符标记,而不会被误解为移位运算符 `>>`。
|
||||
|
||||
要学习如何自定义新的运算符,请参考 [自定义操作符](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_48) 和 [运算符声明](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-XID_644)。学习如何重写现有运算符,请参考 [运算符方法](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_43)。
|
||||
|
||||
> 运算符语法
|
||||
>
|
||||
>
|
||||
> *operator* → [operator-character](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator-character) [operator](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator) *opt*
|
||||
>
|
||||
>
|
||||
> *operator-character* → **/** | **=** | **-** | **+** | **!** | ***** | **%** | **<** | **>** | **&** | **|** | **^** | **~** | **.**
|
||||
>
|
||||
>
|
||||
> *binary-operator* → [operator](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator)
|
||||
>
|
||||
>
|
||||
> *prefix-operator* → [operator](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator)
|
||||
>
|
||||
> *postfix-operator* → [operator](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator)
|
||||
>
|
||||
> *postfix-operator* → [operator](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/operator)
|
||||
|
||||
@ -1,33 +1,38 @@
|
||||
> 翻译:lyuka
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 类型(Types)
|
||||
-----------------
|
||||
|
||||
本页包含内容:
|
||||
|
||||
- 类型标注(Type Annotation)
|
||||
- 类型标识符(Type Identifier)
|
||||
- 元组类型(Tuple Type)
|
||||
- 函数类型(Function Type)
|
||||
- 数组类型(Array Type)
|
||||
- 可选类型(Optional Type)
|
||||
- 隐式解析可选类型(Implicitly Unwrapped Optional Type)
|
||||
- 协议合成类型(Protocol Composition Type)
|
||||
- 元类型(Metatype Type)
|
||||
- 类型继承子句(Type Inheritance Clause)
|
||||
- 类型推断(Type Inference)
|
||||
- [类型注解(Type Annotation)](#type_annotation)
|
||||
- [类型标识符(Type Identifier)](#type_identifier)
|
||||
- [元组类型(Tuple Type)](#tuple_type)
|
||||
- [函数类型(Function Type)](#function_type)
|
||||
- [数组类型(Array Type)](#array_type)
|
||||
- [可选类型(Optional Type)](#optional_type)
|
||||
- [隐式解析可选类型(Implicitly Unwrapped Optional Type)](#implicitly_unwrapped_optional_type)
|
||||
- [协议合成类型(Protocol Composition Type)](#protocol_composition_type)
|
||||
- [元类型(Metatype Type)](#metatype_type)
|
||||
- [类型继承子句(Type Inheritance Clause)](#type_inheritance_clause)
|
||||
- [类型推断(Type Inference)](#type_inference)
|
||||
|
||||
Swift语言存在两种类型:命名型类型和复合型类型。*命名型类型*是指定义时可以给定名字的类型。命名型类型包括类、结构体、枚举和协议。比如,一个用户定义的类`MyClass`的实例拥有类型`MyClass`。除了用户定义的命名型类型,Swift标准库也定义了很多常用的命名型类型,包括那些表示数组、字典和可选值的类型。
|
||||
Swift 语言存在两种类型:命名型类型和复合型类型。*命名型类型*是指定义时可以给定名字的类型。命名型类型包括类、结构体、枚举和协议。比如,一个用户定义的类`MyClass`的实例拥有类型`MyClass`。除了用户定义的命名型类型,Swift 标准库也定义了很多常用的命名型类型,包括那些表示数组、字典和可选值的类型。
|
||||
|
||||
那些通常被其它语言认为是基本或初级的数据型类型(Data types)——比如表示数字、字符和字符串——实际上就是命名型类型,Swift标准库是使用结构体定义和实现它们的。因为它们是命名型类型,因此你可以按照“扩展和扩展声明”章节里讨论的那样,声明一个扩展来增加它们的行为以适应你程序的需求。
|
||||
那些通常被其它语言认为是基本或初级的数据型类型(Data types)——比如表示数字、字符和字符串——实际上就是命名型类型,Swift 标准库是使用结构体定义和实现它们的。因为它们是命名型类型,因此你可以按照“扩展和扩展声明”章节里讨论的那样,声明一个扩展来增加它们的行为以适应你程序的需求。
|
||||
|
||||
*复合型类型*是没有名字的类型,它由Swift本身定义。Swift存在两种复合型类型:函数类型和元组类型。一个复合型类型可以包含命名型类型和其它复合型类型。例如,元组类型`(Int, (Int, Int))`包含两个元素:第一个是命名型类型`Int`,第二个是另一个复合型类型`(Int, Int)`.
|
||||
*复合型类型*是没有名字的类型,它由 Swift 本身定义。Swift 存在两种复合型类型:函数类型和元组类型。一个复合型类型可以包含命名型类型和其它复合型类型。例如,元组类型`(Int, (Int, Int))`包含两个元素:第一个是命名型类型`Int`,第二个是另一个复合型类型`(Int, Int)`.
|
||||
|
||||
本节讨论Swift语言本身定义的类型,并描述Swift中的类型推断行为。
|
||||
本节讨论 Swift 语言本身定义的类型,并描述 Swift 中的类型推断行为。
|
||||
|
||||
>类型的语法:
|
||||
*type* → *array-type* | *function-type* | *type-identifier* | *tuple-type* | *optional-type* | *implicitly-unwrapped-optional-type* | protocol-composition-type | metatype-type
|
||||
|
||||
##类型标注
|
||||
类型标注显式地指定一个变量或表达式的值。类型标注始于冒号`:`终于类型,比如下面两个例子:
|
||||
<a name="type_annotation"></a>
|
||||
##类型注解
|
||||
类型注解显式地指定一个变量或表达式的值。类型注解始于冒号`:`终于类型,比如下面两个例子:
|
||||
|
||||
```javascript
|
||||
let someTuple:(Double, Double) = (3.14159, 2.71828)
|
||||
@ -35,11 +40,12 @@ func someFunction(a: Int){ /* ... */ }
|
||||
```
|
||||
在第一个例子中,表达式`someTuple`的类型被指定为`(Double, Double)`。在第二个例子中,函数`someFunction`的参数`a`的类型被指定为`Int`。
|
||||
|
||||
类型标注可以在类型之前包含一个类型特性(type attributes)的可选列表。
|
||||
类型注解可以在类型之前包含一个类型特性(type attributes)的可选列表。
|
||||
|
||||
>类型标注的语法:
|
||||
>类型注解的语法:
|
||||
*type-annotation* → :*attributes*[opt] *type*
|
||||
|
||||
<a name="type_identifier"></a>
|
||||
##类型标识符
|
||||
类型标识符引用命名型类型或者是命名型/复合型类型的别名。
|
||||
|
||||
@ -62,6 +68,7 @@ var someValue: ExampleModule.MyType
|
||||
*type-identifier* → *type-name generic-argument-clause*[opt] | *type-name generic-argument-clause*[opt].*type-identifier*
|
||||
*type-name* → *identifier*
|
||||
|
||||
<a name="tuple_type"></a>
|
||||
##元组类型
|
||||
元组类型使用逗号隔开并使用括号括起来的0个或多个类型组成的列表。
|
||||
|
||||
@ -72,10 +79,11 @@ var someValue: ExampleModule.MyType
|
||||
>元组类型语法:
|
||||
*tuple* → (*tuple-type-body*[opt])
|
||||
*tuple-type-body* → *tuple-type-element-list* ...[opt]
|
||||
*tuple-type-element-list* → *tuple-type-element* | *tuple-type-element*, *tuple-type-element-list*
|
||||
*tuple-type-element* → *attributes*[opt] **inout** [opt] *type* | **inout** [opt] *element-name type-annotation*
|
||||
*tuple-type-element-list* → *tuple-type-element* | *tuple-type-element*, *tuple-type-element-list*
|
||||
*tuple-type-element* → *attributes*[opt] **inout** [opt] *type* | **inout** [opt] *element-name type-annotation*
|
||||
*element-name* → *identifier*
|
||||
|
||||
<a name="function_type"></a>
|
||||
##函数类型
|
||||
函数类型表示一个函数、方法或闭包的类型,它由一个参数类型和返回值类型组成,中间用箭头`->`隔开:
|
||||
|
||||
@ -121,6 +129,7 @@ addTwoNumbers(4)(5) // Returns 9
|
||||
>函数类型的语法:
|
||||
*function-type* → *type* **->** *type*
|
||||
|
||||
<a name="array_type"></a>
|
||||
##数组类型
|
||||
Swift语言使用类型名紧接中括号`[]`来简化标准库中定义的命名型类型`Array<T>`。换句话说,下面两个声明是等价的:
|
||||
|
||||
@ -147,6 +156,7 @@ var array3D: Int[][][] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
|
||||
>数组类型的语法:
|
||||
*array-type* → *type*`[ ]` | *array-type*`[ ]`
|
||||
|
||||
<a name="optional_type"></a>
|
||||
##可选类型
|
||||
Swift定义后缀`?`来作为标准库中的定义的命名型类型`Optional<T>`的简写。换句话说,下面两个声明是等价的:
|
||||
|
||||
@ -177,6 +187,7 @@ optionalInteger! // 42
|
||||
>可选类型语法:
|
||||
*optional-type* → *type*?
|
||||
|
||||
<a name="implicitly_unwrapped_optional_type"></a>
|
||||
##隐式解析可选类型
|
||||
Swift语言定义后缀`!`作为标准库中命名类型`ImplicitlyUnwrappedOptional<T>`的简写。换句话说,下面两个声明等价:
|
||||
|
||||
@ -199,8 +210,9 @@ var implicitlyUnwrappedString: ImplicitlyUnwrappedOptional<String>
|
||||
>隐式解析可选的语法:
|
||||
implicitly-unwrapped-optional-type → type!
|
||||
|
||||
<a name="protocol_composition_type"></a>
|
||||
##协议合成类型
|
||||
协议合成类型是一种符合每个协议的指定协议列表类型。协议合成类型可能会用在类型标注和泛型参数中。
|
||||
协议合成类型是一种符合每个协议的指定协议列表类型。协议合成类型可能会用在类型注解和泛型参数中。
|
||||
|
||||
协议合成类型的形式如下:
|
||||
```javascript
|
||||
@ -212,9 +224,10 @@ protocol<Protocol 1, Procotol 2>
|
||||
|
||||
>协议合成类型的语法:
|
||||
*protocol-composition-type* → **protocol** <*protocol-identifier-list[opt]*>
|
||||
*protocol-identifier-list* → *protocol-identifier* | *protocol-identifier, protocol-identifier-list*
|
||||
*protocol-identifier-list* → *protocol-identifier* | *protocol-identifier, protocol-identifier-list*
|
||||
*protocol-identifier* → *type-identifier*
|
||||
|
||||
<a name="metatype_type"></a>
|
||||
##元类型
|
||||
元类型是指所有类型的类型,包括类、结构体、枚举和协议。
|
||||
|
||||
@ -243,6 +256,7 @@ someInstance.dynamicType.printClassName()
|
||||
>元类型的语法:
|
||||
*metatype-type* → *type*.**Type** | *type*.**Protocol**
|
||||
|
||||
<a name="type_inheritance_clause"></a>
|
||||
##类型继承子句
|
||||
类型继承子句被用来指定一个命名型类型继承哪个类且适配哪些协议。类型继承子句开始于冒号`:`,紧跟由`,`隔开的类型标识符列表。
|
||||
|
||||
@ -253,19 +267,20 @@ someInstance.dynamicType.printClassName()
|
||||
枚举定义中的类型继承子句可以是一个协议列表,或是指定原始值的枚举,一个单独的指定原始值类型的命名型类型。使用类型继承子句来指定原始值类型的枚举定义的例子,见章节“原始值”。
|
||||
|
||||
>类型继承子句的语法:
|
||||
*type-inheritance-clause* → :*type-inheritance-list*
|
||||
*type-inheritance-clause* → :*type-inheritance-list*
|
||||
*type-inheritance-list* → *type-identifier* | *type-identifier*, *type-inheritance-list*
|
||||
|
||||
<a name="type_inference"></a>
|
||||
##类型推断
|
||||
Swift广泛的使用类型推断,从而允许你可以忽略很多变量和表达式的类型或部分类型。比如,对于`var x: Int = 0`,你可以完全忽略类型而简写成`var x = 0`——编译器会正确的推断出`x`的类型`Int`。类似的,当完整的类型可以从上下文推断出来时,你也可以忽略类型的一部分。比如,如果你写了`let dict: Dictionary = ["A": 1]`,编译提也能推断出`dict`的类型是`Dictionary<String, Int>`。
|
||||
|
||||
在上面的两个例子中,类型信息从表达式树(expression tree)的叶子节点传向根节点。也就是说,`var x: Int = 0`中`x`的类型首先根据`0`的类型进行推断,然后将该类型信息传递到根节点(变量`x`)。
|
||||
|
||||
在Swift中,类型信息也可以反方向流动——从根节点传向叶子节点。在下面的例子中,常量`eFloat`上的显式类型标注(`:Float`)导致数字字面量`2.71828`的类型是`Float`而非`Double`。
|
||||
在Swift中,类型信息也可以反方向流动——从根节点传向叶子节点。在下面的例子中,常量`eFloat`上的显式类型注解(`:Float`)导致数字字面量`2.71828`的类型是`Float`而非`Double`。
|
||||
|
||||
```javascript
|
||||
let e = 2.71828 // The type of e is inferred to be Double.
|
||||
let eFloat: Float = 2.71828 // The type of eFloat is Float.
|
||||
```
|
||||
|
||||
Swift中的类型推断在单独的表达式或语句水平上进行。这意味着所有用于推断类型的信息必须可以从表达式或其某个子表达式的类型检查中获取。
|
||||
Swift中的类型推断在单独的表达式或语句水平上进行。这意味着所有用于推断类型的信息必须可以从表达式或其某个子表达式的类型检查中获取。
|
||||
|
||||
@ -1,27 +1,41 @@
|
||||
# 表达式(Expressions)
|
||||
> 翻译:sg552
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 表达式(Expressions)
|
||||
-----------------
|
||||
|
||||
Swift 中存在四种表达式: 前缀(prefix)表达式,二元(binary)表达式,主要(primary)表达式和后缀(postfix)表达式。表达式可以返回一个值,以及运行某些逻辑(causes a side effect)。
|
||||
本页包含内容:
|
||||
|
||||
前缀表达式和二元表达式就是对某些表达式使用各种运算符(operators)。 主要表达式是最短小的表达式,它提供了获取(变量的)值的一种途径。 后缀表达式则允许你建立复杂的表达式,例如配合函数调用和成员访问。 每种表达式都在下面有详细论述~
|
||||
- [前缀表达式(Prefix Expressions)]
|
||||
- [二元表达式(Binary Expressions)]
|
||||
- [赋值表达式(Assignment Operator)]
|
||||
- [三元条件运算符(Ternary Conditional Operator)]
|
||||
- [类型转换运算符(Type-Casting Operators)]
|
||||
- [主要表达式(Primary Expressions)]
|
||||
- [后缀表达式(Postfix Expressions)]
|
||||
|
||||
Swift 中存在四种表达式: 前缀(prefix)表达式,二元(binary)表达式,主要(primary)表达式和后缀(postfix)表达式。表达式可以返回一个值,以及运行某些逻辑(causes a side effect)。
|
||||
|
||||
前缀表达式和二元表达式就是对某些表达式使用各种运算符(operators)。 主要表达式是最短小的表达式,它提供了获取(变量的)值的一种途径。 后缀表达式则允许你建立复杂的表达式,例如配合函数调用和成员访问。 每种表达式都在下面有详细论述~
|
||||
|
||||
> 表达式的语法
|
||||
>
|
||||
> *expression* → *prefix-expression**binary-expressions*(opt)
|
||||
> *expression* → *prefix-expression**binary-expressions(*opt)
|
||||
> *expression-list* → *expression*| *expression*,*expression-list*
|
||||
|
||||
## 前缀表达式(Prefix Expressions)
|
||||
## 前缀表达式(Prefix Expressions)
|
||||
|
||||
前缀表达式由 前缀符号和表达式组成。(这个前缀符号只能接收一个参数)
|
||||
前缀表达式由 前缀符号和表达式组成。(这个前缀符号只能接收一个参数)
|
||||
|
||||
Swift 标准库支持如下的前缀操作符:
|
||||
|
||||
- ++ 自增1 (increment)
|
||||
- -- 自减1 (decrement)
|
||||
- ! 逻辑否 (Logical NOT )
|
||||
- ~ 按位否 (Bitwise NOT )
|
||||
- \+ 加(Unary plus)
|
||||
- \- 减(Unary minus)
|
||||
- ++ 自增1 (increment)
|
||||
- -- 自减1 (decrement)
|
||||
- ! 逻辑否 (Logical NOT )
|
||||
- ~ 按位否 (Bitwise NOT )
|
||||
- \+ 加(Unary plus)
|
||||
- \- 减(Unary minus)
|
||||
|
||||
对于这些操作符的使用,请参见: Basic Operators and Advanced Operators
|
||||
|
||||
@ -33,7 +47,7 @@ Swift 标准库支持如下的前缀操作符:
|
||||
> *prefix-expression* → *in-out-expression*
|
||||
> *in-out-expression* → &*identifier*
|
||||
|
||||
## 二元表达式( Binary Expressions)
|
||||
## 二元表达式(Binary Expressions)
|
||||
|
||||
二元表达式由 "左边参数" + "二元运算符" + "右边参数" 组成, 它有如下的形式:
|
||||
|
||||
@ -42,30 +56,30 @@ Swift 标准库支持如下的前缀操作符:
|
||||
Swift 标准库提供了如下的二元运算符:
|
||||
|
||||
- 求幂相关(无结合,优先级160)
|
||||
- << 按位左移(Bitwise left shift)
|
||||
- >> 按位右移(Bitwise right shift)
|
||||
- << 按位左移(Bitwise left shift)
|
||||
- >> 按位右移(Bitwise right shift)
|
||||
- 乘除法相关(左结合,优先级150)
|
||||
- \* 乘
|
||||
- / 除
|
||||
- % 求余
|
||||
- &* 乘法,忽略溢出( Multiply, ignoring overflow)
|
||||
- &/ 除法,忽略溢出(Divide, ignoring overflow)
|
||||
- &% 求余, 忽略溢出( Remainder, ignoring overflow)
|
||||
- & 位与( Bitwise AND)
|
||||
- 加减法相关(左结合, 优先级140)
|
||||
- &* 乘法,忽略溢出( Multiply, ignoring overflow)
|
||||
- &/ 除法,忽略溢出(Divide, ignoring overflow)
|
||||
- &% 求余, 忽略溢出( Remainder, ignoring overflow)
|
||||
- & 位与( Bitwise AND)
|
||||
- 加减法相关(左结合, 优先级140)
|
||||
- \+ 加
|
||||
- \- 减
|
||||
- &+ Add with overflow
|
||||
- &- Subtract with overflow
|
||||
- | 按位或(Bitwise OR )
|
||||
- ^ 按位异或(Bitwise XOR)
|
||||
- Range (无结合,优先级 135)
|
||||
- | 按位或(Bitwise OR )
|
||||
- ^ 按位异或(Bitwise XOR)
|
||||
- Range (无结合,优先级 135)
|
||||
- .. 半闭值域 Half-closed range
|
||||
- ... 全闭值域 Closed range
|
||||
- 类型转换 (无结合,优先级 132)
|
||||
- is 类型检查( type check)
|
||||
- as 类型转换( type cast)
|
||||
- Comparative (无结合,优先级 130)
|
||||
- 类型转换 (无结合,优先级 132)
|
||||
- is 类型检查( type check)
|
||||
- as 类型转换( type cast)
|
||||
- Comparative (无结合,优先级 130)
|
||||
- < 小于
|
||||
- <= 小于等于
|
||||
- > 大于
|
||||
@ -74,15 +88,15 @@ Swift 标准库提供了如下的二元运算符:
|
||||
- != 不等
|
||||
- === 恒等于
|
||||
- !== 不恒等
|
||||
- ~= 模式匹配( Pattern match)
|
||||
- 合取( Conjunctive) (左结合,优先级 120)
|
||||
- && 逻辑与(Logical AND)
|
||||
- 析取(Disjunctive) (左结合,优先级 110)
|
||||
- || 逻辑或( Logical OR)
|
||||
- 三元条件(Ternary Conditional )(右结合,优先级 100)
|
||||
- ~= 模式匹配( Pattern match)
|
||||
- 合取( Conjunctive) (左结合,优先级 120)
|
||||
- && 逻辑与(Logical AND)
|
||||
- 析取(Disjunctive) (左结合,优先级 110)
|
||||
- || 逻辑或( Logical OR)
|
||||
- 三元条件(Ternary Conditional )(右结合,优先级 100)
|
||||
- ?: 三元条件 Ternary conditional
|
||||
- 赋值 (Assignment) (右结合, 优先级 90)
|
||||
- = 赋值(Assign)
|
||||
- 赋值 (Assignment) (右结合, 优先级 90)
|
||||
- = 赋值(Assign)
|
||||
- *= Multiply and assign
|
||||
- /= Divide and assign
|
||||
- %= Remainder and assign
|
||||
@ -96,11 +110,11 @@ Swift 标准库提供了如下的二元运算符:
|
||||
- &&= Logical AND and assign
|
||||
- ||= Logical OR and assign
|
||||
|
||||
关于这些运算符(operators)的更多信息,请参见:Basic Operators and Advanced Operators.
|
||||
关于这些运算符(operators)的更多信息,请参见:Basic Operators and Advanced Operators.
|
||||
|
||||
>> 注意
|
||||
>>
|
||||
>> 在解析时, 一个二元表达式表示为一个一级数组(a flat list), 这个数组(List)根据运算符的先后顺序,被转换成了一个tree. 例如: 2 + 3 * 5 首先被认为是: 2, + , `` 3``, *, 5. 随后它被转换成 tree (2 + (3 * 5))
|
||||
>> 在解析时, 一个二元表达式表示为一个一级数组(a flat list), 这个数组(List)根据运算符的先后顺序,被转换成了一个tree. 例如: 2 + 3 * 5 首先被认为是: 2, + , `` 3``, *, 5. 随后它被转换成 tree (2 + (3 * 5))
|
||||
|
||||
> 二元表达式的语法
|
||||
>
|
||||
@ -108,16 +122,16 @@ Swift 标准库提供了如下的二元运算符:
|
||||
> *binary-expression* → *assignment-operator*prefix-expression*
|
||||
> *binary-expression* → *conditional-operator*prefix-expression*
|
||||
> *binary-expression* → *type-casting-operator*
|
||||
> *binary-expression*s → *binary-expression**binary-expressions*(opt)
|
||||
> *binary-expression*s → *binary-expression**binary-expressions*(opt)
|
||||
|
||||
## 赋值表达式( Assignment Operator)
|
||||
## 赋值表达式(Assignment Operator)
|
||||
|
||||
The assigment operator sets a new value for a given expression. It has the following form:
|
||||
赋值表达式会对某个给定的表达式赋值。 它有如下的形式;
|
||||
|
||||
`expression` = `value`
|
||||
|
||||
就是把右边的 *value* 赋值给左边的 *expression*. 如果左边的*expression* 需要接收多个参数(是一个tuple ),那么右边必须也是一个具有同样数量参数的tuple. (允许嵌套的tuple)
|
||||
就是把右边的 *value* 赋值给左边的 *expression*. 如果左边的*expression* 需要接收多个参数(是一个tuple ),那么右边必须也是一个具有同样数量参数的tuple. (允许嵌套的tuple)
|
||||
|
||||
```swift
|
||||
(a, _, (b, c)) = ("test", 9.45, (12, 3))
|
||||
@ -130,13 +144,13 @@ The assigment operator sets a new value for a given expression. It has the follo
|
||||
>
|
||||
> *assignment-operator* → =
|
||||
|
||||
## 三元条件运算符(Ternary Conditional Operator)
|
||||
## 三元条件运算符(Ternary Conditional Operator)
|
||||
|
||||
三元条件运算符 是根据条件来获取值。 形式如下:
|
||||
|
||||
`condition` ? `expression used if true` : `expression used if false`
|
||||
|
||||
如果 `condition` 是true, 那么返回 第一个表达式的值(此时不会调用第二个表达式), 否则返回第二个表达式的值(此时不会调用第一个表达式)。
|
||||
如果 `condition` 是true, 那么返回 第一个表达式的值(此时不会调用第二个表达式), 否则返回第二个表达式的值(此时不会调用第一个表达式)。
|
||||
|
||||
想看三元条件运算符的例子,请参见: Ternary Conditional Operator.
|
||||
|
||||
@ -144,7 +158,7 @@ The assigment operator sets a new value for a given expression. It has the follo
|
||||
>
|
||||
> `conditional-operator` → ?`expression`:
|
||||
|
||||
## 类型转换运算符(Type-Casting Operators)
|
||||
## 类型转换运算符(Type-Casting Operators)
|
||||
|
||||
有两种类型转换操作符: as 和 is. 它们有如下的形式:
|
||||
|
||||
@ -152,13 +166,13 @@ The assigment operator sets a new value for a given expression. It has the follo
|
||||
`expression` as? `type`
|
||||
`expression` is `type`
|
||||
|
||||
as 运算符会把`目标表达式`转换成指定的`类型`(specified type),过程如下:
|
||||
as 运算符会把`目标表达式`转换成指定的`类型`(specified type),过程如下:
|
||||
|
||||
- 如果类型转换成功, 那么目标表达式就会返回指定类型的实例(instance). 例如:把子类(subclass)变成父类(superclass)时.
|
||||
- 如果类型转换成功, 那么目标表达式就会返回指定类型的实例(instance). 例如:把子类(subclass)变成父类(superclass)时.
|
||||
|
||||
- 如果转换失败,则会抛出编译错误( compile-time error)。
|
||||
- 如果转换失败,则会抛出编译错误( compile-time error)。
|
||||
|
||||
- 如果上述两个情况都不是(也就是说,编译器在编译时期无法确定转换能否成功,) 那么目标表达式就会变成指定的类型的optional. (is an optional of the specified type ) 然后在运行时,如果转换成功, 目标表达式就会作为 optional的一部分来返回, 否则,目标表达式返回nil. 对应的例子是: 把一个 superclass 转换成一个 subclass.
|
||||
- 如果上述两个情况都不是(也就是说,编译器在编译时期无法确定转换能否成功,) 那么目标表达式就会变成指定的类型的optional. (is an optional of the specified type ) 然后在运行时,如果转换成功, 目标表达式就会作为 optional的一部分来返回, 否则,目标表达式返回nil. 对应的例子是: 把一个 superclass 转换成一个 subclass.
|
||||
|
||||
```swift
|
||||
class SomeSuperType {}
|
||||
@ -178,10 +192,10 @@ let y1 = x as SomeType // Type information from 'as'
|
||||
let y2: SomeType = x // Type information from an annotation
|
||||
```
|
||||
|
||||
'is' 运算符在“运行时(runtime)”会做检查。 成功会返回true, 否则 false
|
||||
'is' 运算符在“运行时(runtime)”会做检查。 成功会返回true, 否则 false
|
||||
|
||||
The check must not be known to be true or false at compile time. The following are invalid:
|
||||
上述检查在“编译时(compile time)”不能使用。 例如下面的使用是错误的:
|
||||
上述检查在“编译时(compile time)”不能使用。 例如下面的使用是错误的:
|
||||
|
||||
```swift
|
||||
"hello" is String
|
||||
@ -194,13 +208,13 @@ The check must not be known to be true or false at compile time. The following a
|
||||
>
|
||||
> *type-casting-operator* → is*type*| as?(opt)*type*
|
||||
|
||||
## 主要表达式(Primary Expressions)
|
||||
## 主要表达式(Primary Expressions)
|
||||
|
||||
`主要表达式`是最基本的表达式。 它们可以跟 前缀表达式,二元表达式,后缀表达式以及其他主要表达式组合使用。
|
||||
|
||||
> 主要表达式的语法
|
||||
>
|
||||
> *primary-expression* → *identifier**generic-argument-clause*(opt)
|
||||
> *primary-expression* → *identifier**generic-argument-clause*(opt)
|
||||
> *primary-expression* → *literal-expression*
|
||||
> *primary-expression* → *self-expression*
|
||||
> *primary-expression* → *superclass-expression*
|
||||
@ -209,30 +223,30 @@ The check must not be known to be true or false at compile time. The following a
|
||||
> *primary-expression* → *implicit-member-expression*
|
||||
> *primary-expression* → *wildcard-expression*
|
||||
|
||||
### 字符型表达式(Literal Expression)
|
||||
### 字符型表达式(Literal Expression)
|
||||
|
||||
由这些内容组成:普通的字符(string, number) , 一个字符的字典或者数组,或者下面列表中的特殊字符。
|
||||
由这些内容组成:普通的字符(string, number) , 一个字符的字典或者数组,或者下面列表中的特殊字符。
|
||||
|
||||
字符(Literal) | 类型(Type) | 值(Value)
|
||||
字符(Literal) | 类型(Type) | 值(Value)
|
||||
------------- | ---------- | ----------
|
||||
\__FILE__ | String | 所在的文件名
|
||||
\__LINE__ | Int | 所在的行数
|
||||
\__COLUMN__ | Int | 所在的列数
|
||||
\__FUNCTION__ | String | 所在的function 的名字
|
||||
|
||||
在某个函数(function)中,`__FUNCTION__` 会返回当前函数的名字。 在某个方法(method)中,它会返回当前方法的名字。 在某个property 的getter/setter中会返回这个属性的名字。 在init/subscript中 只有的特殊成员(member)中会返回这个keyword的名字,在某个文件的顶端(the top level of a file),它返回的是当前module的名字。
|
||||
在某个函数(function)中,`__FUNCTION__` 会返回当前函数的名字。 在某个方法(method)中,它会返回当前方法的名字。 在某个property 的getter/setter中会返回这个属性的名字。 在init/subscript中 只有的特殊成员(member)中会返回这个keyword的名字,在某个文件的顶端(the top level of a file),它返回的是当前module的名字。
|
||||
|
||||
一个array literal,是一个有序的值的集合。 它的形式是:
|
||||
|
||||
[`value 1`, `value 2`, `...`]
|
||||
|
||||
数组中的最后一个表达式可以紧跟一个逗号(','). []表示空数组 。 array literal的type是 T[], 这个T就是数组中元素的type. 如果该数组中有多种type, T则是跟这些type的公共supertype最接近的type.(closest common supertype)
|
||||
数组中的最后一个表达式可以紧跟一个逗号(','). []表示空数组 。 array literal的type是 T[], 这个T就是数组中元素的type. 如果该数组中有多种type, T则是跟这些type的公共supertype最接近的type.(closest common supertype)
|
||||
|
||||
一个`dictionary literal` 是一个包含无序的键值对(key-value pairs)的集合,它的形式是:
|
||||
一个`dictionary literal` 是一个包含无序的键值对(key-value pairs)的集合,它的形式是:
|
||||
|
||||
[`key 1`: `value 1`, `key 2`: `value 2`, `...`]
|
||||
|
||||
dictionary 的最后一个表达式可以是一个逗号(','). [:] 表示一个空的dictionary. 它的type是 Dictionary<KeyType, ValueType> (这里KeyType表示 key的type, ValueType表示 value的type) 如果这个dictionary 中包含多种 types, 那么KeyType, Value 则对应着它们的公共supertype最接近的type( closest common supertype).
|
||||
dictionary 的最后一个表达式可以是一个逗号(','). [:] 表示一个空的dictionary. 它的type是 Dictionary<KeyType, ValueType> (这里KeyType表示 key的type, ValueType表示 value的type) 如果这个dictionary 中包含多种 types, 那么KeyType, Value 则对应着它们的公共supertype最接近的type( closest common supertype).
|
||||
|
||||
> 字符型表达式的语法
|
||||
>
|
||||
@ -246,25 +260,25 @@ dictionary 的最后一个表达式可以是一个逗号(','). [:] 表示一个
|
||||
> *dictionary-literal-items* → *dictionary-literal-item*,(opt)| *dictionary-literal-item*,*dictionary-literal-items*
|
||||
> *dictionary-literal-item* → *expression*:*expression*
|
||||
|
||||
### self表达式(Self Expression)
|
||||
### self表达式(Self Expression)
|
||||
|
||||
self表达式是对 当前type 或者当前instance的引用。它的形式如下:
|
||||
|
||||
> self
|
||||
> self.`member name`
|
||||
> self[`subscript index`]
|
||||
> self(`initializer arguments`)
|
||||
> self.init(`initializer arguments`)
|
||||
> self(`initializer arguments`)
|
||||
> self.init(`initializer arguments`)
|
||||
|
||||
如果在 initializer, subscript, instance method中,self等同于当前type的instance. 在一个静态方法(static method), 类方法(class method)中, self等同于当前的type.
|
||||
如果在 initializer, subscript, instance method中,self等同于当前type的instance. 在一个静态方法(static method), 类方法(class method)中, self等同于当前的type.
|
||||
|
||||
当访问 member(成员变量时), self 用来区分重名变量(例如函数的参数). 例如,
|
||||
(下面的 self.greeting 指的是 var greeting: String, 而不是 init(greeting: String) )
|
||||
当访问 member(成员变量时), self 用来区分重名变量(例如函数的参数). 例如,
|
||||
(下面的 self.greeting 指的是 var greeting: String, 而不是 init(greeting: String) )
|
||||
|
||||
```swift
|
||||
class SomeClass {
|
||||
var greeting: String
|
||||
init(greeting: String) {
|
||||
init(greeting: String) {
|
||||
self.greeting = greeting
|
||||
}
|
||||
}
|
||||
@ -275,8 +289,8 @@ class SomeClass {
|
||||
```swift
|
||||
struct Point {
|
||||
var x = 0.0, y = 0.0
|
||||
mutating func moveByX(deltaX: Double, y deltaY: Double) {
|
||||
self = Point(x: x + deltaX, y: y + deltaY)
|
||||
mutating func moveByX(deltaX: Double, y deltaY: Double) {
|
||||
self = Point(x: x + deltaX, y: y + deltaY)
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -288,17 +302,17 @@ struct Point {
|
||||
> *self-expression* → self[*expression*]
|
||||
> *self-expression* → self.init
|
||||
|
||||
### 超类表达式(Superclass Expression)
|
||||
### 超类表达式(Superclass Expression)
|
||||
|
||||
超类表达式可以使我们在某个class中访问它的超类. 它有如下形式:
|
||||
|
||||
super.`member name`
|
||||
super[`subscript index`]
|
||||
super.init(`initializer arguments`)
|
||||
super.init(`initializer arguments`)
|
||||
|
||||
形式1 用来访问超类的某个成员(member). 形式2 用来访问该超类的 subscript 实现。 形式3 用来访问该超类的 initializer.
|
||||
形式1 用来访问超类的某个成员(member). 形式2 用来访问该超类的 subscript 实现。 形式3 用来访问该超类的 initializer.
|
||||
|
||||
子类(subclass)可以通过超类(superclass)表达式在它们的 member, subscripting 和 initializers 中来利用它们超类中的某些实现(既有的方法或者逻辑)。
|
||||
子类(subclass)可以通过超类(superclass)表达式在它们的 member, subscripting 和 initializers 中来利用它们超类中的某些实现(既有的方法或者逻辑)。
|
||||
|
||||
> GRAMMAR OF A SUPERCLASS EXPRESSION
|
||||
|
||||
@ -307,12 +321,12 @@ struct Point {
|
||||
> *superclass-subscript-expression* → super[*expression*]
|
||||
> *superclass-initializer-expression* → super.init
|
||||
|
||||
### 闭包表达式(Closure Expression)
|
||||
### 闭包表达式(Closure Expression)
|
||||
|
||||
闭包(closure) 表达式可以建立一个闭包(在其他语言中也叫 lambda, 或者 匿名函数(anonymous function)). 跟函数(function)的声明一样, 闭包(closure)包含了可执行的代码(跟方法主体(statement)类似) 以及接收(capture)的参数。 它的形式如下:
|
||||
闭包(closure) 表达式可以建立一个闭包(在其他语言中也叫 lambda, 或者 匿名函数(anonymous function)). 跟函数(function)的声明一样, 闭包(closure)包含了可执行的代码(跟方法主体(statement)类似) 以及接收(capture)的参数。 它的形式如下:
|
||||
|
||||
```swift
|
||||
{ (parameters) -> return type in
|
||||
{ (parameters) -> return type in
|
||||
statements
|
||||
}
|
||||
```
|
||||
@ -321,20 +335,20 @@ struct Point {
|
||||
|
||||
闭包还有几种特殊的形式, 让使用更加简洁:
|
||||
|
||||
- 闭包可以省略 它的参数的type 和返回值的type. 如果省略了参数和参数类型,就也要省略 'in'关键字。 如果被省略的type 无法被编译器获知(inferred) ,那么就会抛出编译错误。
|
||||
- 闭包可以省略参数,转而在方法体(statement)中使用 $0, $1, $2 来引用出现的第一个,第二个,第三个参数。
|
||||
- 闭包可以省略 它的参数的type 和返回值的type. 如果省略了参数和参数类型,就也要省略 'in'关键字。 如果被省略的type 无法被编译器获知(inferred) ,那么就会抛出编译错误。
|
||||
- 闭包可以省略参数,转而在方法体(statement)中使用 $0, $1, $2 来引用出现的第一个,第二个,第三个参数。
|
||||
- 如果闭包中只包含了一个表达式,那么该表达式就会自动成为该闭包的返回值。 在执行 'type inference '时,该表达式也会返回。
|
||||
|
||||
下面几个 闭包表达式是 等价的:
|
||||
|
||||
```swift
|
||||
myFunction {
|
||||
(x: Int, y: Int) -> Int in
|
||||
(x: Int, y: Int) -> Int in
|
||||
return x + y
|
||||
}
|
||||
|
||||
myFunction {
|
||||
(x, y) in
|
||||
(x, y) in
|
||||
return x + y
|
||||
}
|
||||
|
||||
@ -345,21 +359,21 @@ myFunction { $0 + $1 }
|
||||
|
||||
关于 向闭包中传递参数的内容,参见: Function Call Expression.
|
||||
|
||||
闭包表达式可以通过一个参数列表(capture list) 来显式指定它需要的参数。 参数列表 由中括号 [] 括起来,里面的参数由逗号','分隔。一旦使用了参数列表,就必须使用'in'关键字(在任何情况下都得这样做,包括忽略参数的名字,type, 返回值时等等)。
|
||||
闭包表达式可以通过一个参数列表(capture list) 来显式指定它需要的参数。 参数列表 由中括号 [] 括起来,里面的参数由逗号','分隔。一旦使用了参数列表,就必须使用'in'关键字(在任何情况下都得这样做,包括忽略参数的名字,type, 返回值时等等)。
|
||||
|
||||
在闭包的参数列表( capture list)中, 参数可以声明为 'weak' 或者 'unowned' .
|
||||
在闭包的参数列表( capture list)中, 参数可以声明为 'weak' 或者 'unowned' .
|
||||
|
||||
```swift
|
||||
myFunction { print(self.title) } // strong capture
|
||||
myFunction { [weak self] in print(self!.title) } // weak capture
|
||||
myFunction { [unowned self] in print(self.title) } // unowned capture
|
||||
myFunction { print(self.title) } // strong capture
|
||||
myFunction { [weak self] in print(self!.title) } // weak capture
|
||||
myFunction { [unowned self] in print(self.title) } // unowned capture
|
||||
```
|
||||
|
||||
在参数列表中,也可以使用任意表达式来赋值. 该表达式会在 闭包被执行时赋值,然后按照不同的力度来获取(这句话请慎重理解)。(captured with the specified strength. ) 例如:
|
||||
在参数列表中,也可以使用任意表达式来赋值. 该表达式会在 闭包被执行时赋值,然后按照不同的力度来获取(这句话请慎重理解)。(captured with the specified strength. ) 例如:
|
||||
|
||||
```swift
|
||||
// Weak capture of "self.parent" as "parent"
|
||||
myFunction { [weak parent = self.parent] in print(parent!.title) }
|
||||
myFunction { [weak parent = self.parent] in print(parent!.title) }
|
||||
```
|
||||
|
||||
关于闭包表达式的更多信息和例子,请参见: Closure Expressions.
|
||||
@ -373,11 +387,11 @@ myFunction { [weak parent = self.parent] in print(parent!.title) }
|
||||
> *closure-signature* → *capture-list**identifier-list**function-result*(opt)in
|
||||
> *closure-signature* → *capture-list*in
|
||||
> *capture-list* → [*capture-specifier**expression*]
|
||||
> *capture-specifier* → weak| unowned| unowned(safe)| unowned(unsafe)
|
||||
> *capture-specifier* → weak| unowned| unowned(safe)| unowned(unsafe)
|
||||
|
||||
### 隐式成员表达式(Implicit Member Expression)
|
||||
### 隐式成员表达式(Implicit Member Expression)
|
||||
|
||||
在可以判断出类型(type)的上下文(context)中,隐式成员表达式是访问某个type的member( 例如 class method, enumeration case) 的简洁方法。 它的形式是:
|
||||
在可以判断出类型(type)的上下文(context)中,隐式成员表达式是访问某个type的member( 例如 class method, enumeration case) 的简洁方法。 它的形式是:
|
||||
|
||||
.`member name`
|
||||
|
||||
@ -392,26 +406,26 @@ x = .AnotherValue
|
||||
>
|
||||
> *implicit-member-expression* → .*identifier*
|
||||
|
||||
### 圆括号表达式(Parenthesized Expression)
|
||||
### 圆括号表达式(Parenthesized Expression)
|
||||
|
||||
圆括号表达式由多个子表达式和逗号','组成。 每个子表达式前面可以有 identifier x: 这样的可选前缀。形式如下:
|
||||
|
||||
(`identifier 1`: `expression 1`, `identifier 2`: `expression 2`, `...`)
|
||||
(`identifier 1`: `expression 1`, `identifier 2`: `expression 2`, `...`)
|
||||
|
||||
圆括号表达式用来建立tuples , 然后把它做为参数传递给 function. 如果某个圆括号表达式中只有一个 子表达式,那么它的type就是 子表达式的type。例如: (1)的 type是Int, 而不是(Int)
|
||||
圆括号表达式用来建立tuples , 然后把它做为参数传递给 function. 如果某个圆括号表达式中只有一个 子表达式,那么它的type就是 子表达式的type。例如: (1)的 type是Int, 而不是(Int)
|
||||
|
||||
> 圆括号表达式的语法
|
||||
>
|
||||
> *parenthesized-expression* → (*expression-element-list* (opt))
|
||||
> *parenthesized-expression* → (*expression-element-list* (opt))
|
||||
> *expression-element-list* → *expression-element*| *expression-element*,*expression-element-list*
|
||||
> *expression-element* → *expression*| *identifier*:*expression*
|
||||
|
||||
### 通配符表达式( Wildcard Expression)
|
||||
### 通配符表达式(Wildcard Expression)
|
||||
|
||||
通配符表达式用来忽略传递进来的某个参数。例如:下面的代码中,10被传递给x, 20被忽略(译注:好奇葩的语法。。。)
|
||||
|
||||
```swift
|
||||
(x, _) = (10, 20)
|
||||
(x, _) = (10, 20)
|
||||
// x is 10, 20 is ignored
|
||||
```
|
||||
|
||||
@ -419,9 +433,9 @@ x = .AnotherValue
|
||||
>
|
||||
> *wildcard-expression* → _
|
||||
|
||||
## 后缀表达式( Postfix Expressions)
|
||||
## 后缀表达式(Postfix Expressions)
|
||||
|
||||
后缀表达式就是在某个表达式的后面加上 操作符。 严格的讲,每个主要表达式(primary expression)都是一个后缀表达式
|
||||
后缀表达式就是在某个表达式的后面加上 操作符。 严格的讲,每个主要表达式(primary expression)都是一个后缀表达式
|
||||
|
||||
Swift 标准库提供了下列后缀表达式:
|
||||
|
||||
@ -443,32 +457,32 @@ Swift 标准库提供了下列后缀表达式:
|
||||
> *postfix-expression* → *forced-value-expression*
|
||||
> *postfix-expression* → *optional-chaining-expression*
|
||||
|
||||
### 函数调用表达式( Function Call Expression)
|
||||
### 函数调用表达式(Function Call Expression)
|
||||
|
||||
函数调用表达式由函数名和参数列表组成。它的形式如下:
|
||||
|
||||
`function name`(`argument value 1`, `argument value 2`)
|
||||
`function name`(`argument value 1`, `argument value 2`)
|
||||
|
||||
The function name can be any expression whose value is of a function type.
|
||||
(不用翻译了, 太罗嗦)
|
||||
(不用翻译了, 太罗嗦)
|
||||
|
||||
如果该function 的声明中指定了参数的名字,那么在调用的时候也必须得写出来. 例如:
|
||||
|
||||
`function name`(`argument name 1`: `argument value 1`, `argument name 2`: `argument value 2`)
|
||||
`function name`(`argument name 1`: `argument value 1`, `argument name 2`: `argument value 2`)
|
||||
|
||||
可以在 函数调用表达式的尾部(最后一个参数之后)加上 一个闭包(closure) , 该闭包会被目标函数理解并执行。它具有如下两种写法:
|
||||
可以在 函数调用表达式的尾部(最后一个参数之后)加上 一个闭包(closure) , 该闭包会被目标函数理解并执行。它具有如下两种写法:
|
||||
|
||||
```swift
|
||||
// someFunction takes an integer and a closure as its arguments
|
||||
someFunction(x, {$0 == 13})
|
||||
someFunction(x) {$0 == 13}
|
||||
someFunction(x, {$0 == 13})
|
||||
someFunction(x) {$0 == 13}
|
||||
```
|
||||
|
||||
如果闭包是该函数的唯一参数,那么圆括号可以省略。
|
||||
|
||||
```swift
|
||||
// someFunction takes a closure as its only argument
|
||||
myData.someMethod() {$0 == 13}
|
||||
myData.someMethod() {$0 == 13}
|
||||
myData.someMethod {$0 == 13}
|
||||
```
|
||||
|
||||
@ -478,26 +492,26 @@ myData.someMethod {$0 == 13}
|
||||
> *function-call-expression* → *postfix-expression**parenthesized-expression*(opt)*trailing-closure*
|
||||
> *trailing-closure* → *closure-expression*
|
||||
|
||||
### 初始化函数表达式(Initializer Expression)
|
||||
### 初始化函数表达式(Initializer Expression)
|
||||
|
||||
Initializer表达式用来给某个Type初始化。 它的形式如下:
|
||||
|
||||
`expression`.init(`initializer arguments`)
|
||||
`expression`.init(`initializer arguments`)
|
||||
|
||||
(Initializer表达式用来给某个Type初始化。) 跟函数(function)不同, initializer 不能返回值。
|
||||
(Initializer表达式用来给某个Type初始化。) 跟函数(function)不同, initializer 不能返回值。
|
||||
|
||||
```swift
|
||||
var x = SomeClass.someClassFunction // ok
|
||||
var y = SomeClass.init // error
|
||||
```swift
|
||||
|
||||
可以通过 initializer 表达式来委托调用(delegate to )到superclass的initializers.
|
||||
可以通过 initializer 表达式来委托调用(delegate to )到superclass的initializers.
|
||||
|
||||
```swift
|
||||
class SomeSubClass: SomeSuperClass {
|
||||
init() {
|
||||
init() {
|
||||
// subclass initialization goes here
|
||||
super.init()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -506,39 +520,39 @@ class SomeSubClass: SomeSuperClass {
|
||||
>
|
||||
> *initializer-expression* → *postfix-expression*.init
|
||||
|
||||
### 显式成员表达式(Explicit Member Expression)
|
||||
### 显式成员表达式(Explicit Member Expression)
|
||||
|
||||
显示成员表达式允许我们访问type, tuple, module的成员变量。它的形式如下:
|
||||
|
||||
`expression`.`member name`
|
||||
|
||||
该member 就是某个type在声明时候所定义(declaration or extension) 的变量, 例如:
|
||||
该member 就是某个type在声明时候所定义(declaration or extension) 的变量, 例如:
|
||||
|
||||
```swift
|
||||
class SomeClass {
|
||||
var someProperty = 42
|
||||
}
|
||||
let c = SomeClass()
|
||||
let c = SomeClass()
|
||||
let y = c.someProperty // Member access
|
||||
```
|
||||
|
||||
对于tuple, 要根据它们出现的顺序(0, 1, 2...)来使用:
|
||||
对于tuple, 要根据它们出现的顺序(0, 1, 2...)来使用:
|
||||
|
||||
```swift
|
||||
var t = (10, 20, 30)
|
||||
var t = (10, 20, 30)
|
||||
t.0 = t.1
|
||||
// Now t is (20, 20, 30)
|
||||
// Now t is (20, 20, 30)
|
||||
```
|
||||
|
||||
The members of a module access the top-level declarations of that module.
|
||||
(不确定:对于某个module的member的调用,只能调用在top-level声明中的member.)
|
||||
(不确定:对于某个module的member的调用,只能调用在top-level声明中的member.)
|
||||
|
||||
> 显示成员表达式的语法
|
||||
>
|
||||
> *explicit-member-expression* → *postfix-expression*.*decimal-digit*
|
||||
> *explicit-member-expression* → *postfix-expression*.*identifier**generic-argument-clause*(opt)
|
||||
|
||||
### 后缀self表达式(Postfix Self Expression)
|
||||
### 后缀self表达式(Postfix Self Expression)
|
||||
|
||||
后缀表达式由 某个表达式 + '.self' 组成. 形式如下:
|
||||
|
||||
@ -553,32 +567,32 @@ The members of a module access the top-level declarations of that module.
|
||||
>
|
||||
> *postfix-self-expression* → *postfix-expression*.self
|
||||
|
||||
### dynamic表达式(Dynamic Type Expression)
|
||||
### dynamic表达式(Dynamic Type Expression)
|
||||
|
||||
(因为dynamicType是一个独有的方法,所以这里保留了英文单词,未作翻译, --- 类似与self expression)
|
||||
(因为dynamicType是一个独有的方法,所以这里保留了英文单词,未作翻译, --- 类似与self expression)
|
||||
|
||||
dynamicType 表达式由 某个表达式 + '.dynamicType' 组成。
|
||||
|
||||
`expression`.dynamicType
|
||||
|
||||
上面的形式中, expression 不能是某type的名字(当然了,如果我都知道它的名字了还需要动态来获取它吗)。动态类型表达式会返回"运行时"某个instance的type, 具体请看下面的列子:
|
||||
上面的形式中, expression 不能是某type的名字(当然了,如果我都知道它的名字了还需要动态来获取它吗)。动态类型表达式会返回"运行时"某个instance的type, 具体请看下面的列子:
|
||||
|
||||
```swift
|
||||
class SomeBaseClass {
|
||||
class func printClassName() {
|
||||
println("SomeBaseClass")
|
||||
class func printClassName() {
|
||||
println("SomeBaseClass")
|
||||
}
|
||||
}
|
||||
class SomeSubClass: SomeBaseClass {
|
||||
override class func printClassName() {
|
||||
println("SomeSubClass")
|
||||
override class func printClassName() {
|
||||
println("SomeSubClass")
|
||||
}
|
||||
}
|
||||
let someInstance: SomeBaseClass = SomeSubClass()
|
||||
let someInstance: SomeBaseClass = SomeSubClass()
|
||||
|
||||
// someInstance is of type SomeBaseClass at compile time, but
|
||||
// someInstance is of type SomeSubClass at runtime
|
||||
someInstance.dynamicType.printClassName()
|
||||
someInstance.dynamicType.printClassName()
|
||||
// prints "SomeSubClass"
|
||||
```
|
||||
|
||||
@ -586,33 +600,33 @@ someInstance.dynamicType.printClassName()
|
||||
>
|
||||
> *dynamic-type-expression* → *postfix-expression*.dynamicType
|
||||
|
||||
### 下标表达式( Subscript Expression)
|
||||
### 附属脚本表达式(Subscript Expression)
|
||||
|
||||
下标表达式提供了通过下标访问getter/setter 的方法。它的形式是:
|
||||
附属脚本表达式提供了通过附属脚本访问getter/setter 的方法。它的形式是:
|
||||
|
||||
`expression`[`index expressions`]
|
||||
|
||||
可以通过下标表达式通过getter获取某个值,或者通过setter赋予某个值.
|
||||
可以通过附属脚本表达式通过getter获取某个值,或者通过setter赋予某个值.
|
||||
|
||||
关于subscript的声明,请参见: Protocol Subscript Declaration.
|
||||
|
||||
> 下标表达式的语法
|
||||
> 附属脚本表达式的语法
|
||||
>
|
||||
> *subscript-expression* → *postfix-expression*[*expression-list*]
|
||||
|
||||
### 强制取值表达式(Forced-Value Expression)
|
||||
### 强制取值表达式(Forced-Value Expression)
|
||||
|
||||
强制取值表达式用来获取某个目标表达式的值(该目标表达式的值必须不是nil )。它的形式如下:
|
||||
强制取值表达式用来获取某个目标表达式的值(该目标表达式的值必须不是nil )。它的形式如下:
|
||||
|
||||
`expression`!
|
||||
|
||||
如果该表达式的值不是nil, 则返回对应的值。 否则,抛出运行时错误(runtime error)。
|
||||
如果该表达式的值不是nil, 则返回对应的值。 否则,抛出运行时错误(runtime error)。
|
||||
|
||||
> 强制取值表达式的语法
|
||||
>
|
||||
> *forced-value-expression* → *postfix-expression*!
|
||||
|
||||
### 可选链表达式(Optional-Chaining Expression)
|
||||
### 可选链表达式(Optional-Chaining Expression)
|
||||
|
||||
可选链表达式由目标表达式 + '?' 组成,形式如下:
|
||||
|
||||
@ -620,20 +634,20 @@ someInstance.dynamicType.printClassName()
|
||||
|
||||
后缀'?' 返回目标表达式的值,把它做为可选的参数传递给后续的表达式
|
||||
|
||||
如果某个后缀表达式包含了可选链表达式,那么它的执行过程就比较特殊: 首先先判断该可选链表达式的值,如果是 nil, 整个后缀表达式都返回 nil, 如果该可选链的值不是nil, 则正常返回该后缀表达式的值(依次执行它的各个子表达式)。在这两种情况下,该后缀表达式仍然是一个optional type(In either case, the value of the postfix expression is still of an optional type)
|
||||
如果某个后缀表达式包含了可选链表达式,那么它的执行过程就比较特殊: 首先先判断该可选链表达式的值,如果是 nil, 整个后缀表达式都返回 nil, 如果该可选链的值不是nil, 则正常返回该后缀表达式的值(依次执行它的各个子表达式)。在这两种情况下,该后缀表达式仍然是一个optional type(In either case, the value of the postfix expression is still of an optional type)
|
||||
|
||||
如果某个"后缀表达式"的"子表达式"中包含了"可选链表达式",那么只有最外层的表达式返回的才是一个optional type. 例如,在下面的例子中, 如果c 不是nil, 那么 c?.property.performAction() 这句代码在执行时,就会先获得c 的property方法,然后调用 performAction()方法。 然后对于 "c?.property.performAction()" 这个整体,它的返回值是一个optional type.
|
||||
如果某个"后缀表达式"的"子表达式"中包含了"可选链表达式",那么只有最外层的表达式返回的才是一个optional type. 例如,在下面的例子中, 如果c 不是nil, 那么 c?.property.performAction() 这句代码在执行时,就会先获得c 的property方法,然后调用 performAction()方法。 然后对于 "c?.property.performAction()" 这个整体,它的返回值是一个optional type.
|
||||
|
||||
```swift
|
||||
var c: SomeClass?
|
||||
var result: Bool? = c?.property.performAction()
|
||||
var result: Bool? = c?.property.performAction()
|
||||
```
|
||||
|
||||
如果不使用可选链表达式,那么 上面例子的代码跟下面例子等价:
|
||||
|
||||
```swift
|
||||
if let unwrappedC = c {
|
||||
result = unwrappedC.property.performAction()
|
||||
result = unwrappedC.property.performAction()
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -0,0 +1,902 @@
|
||||
> 翻译:marsprince
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 声明
|
||||
-----------------
|
||||
|
||||
本页包含内容:
|
||||
|
||||
- [模块范围](#module_scope)
|
||||
- [代码块](#code_blocks)
|
||||
- [引入声明](#import_declaration)
|
||||
- [常量声明](#constant_declaration)
|
||||
- [变量声明](#variable_declaration)
|
||||
- [类型的别名声明](#type_alias_declaration)
|
||||
- [函数声明](#function_declaration)
|
||||
- [枚举声明](#enumeration_declaration)
|
||||
- [结构体声明](#structure_declaration)
|
||||
- [类声明](#class_declaration)
|
||||
- [协议声明](#protocol_declaration)
|
||||
- [构造器声明](#initializer_declaration)
|
||||
- [析构声明](#deinitializer_declaration)
|
||||
- [扩展声明](#extension_declaration)
|
||||
- [附属脚本声明](#subscript_declaration)
|
||||
- [运算符声明](#operator_declaration)
|
||||
|
||||
一条声明可以在你的程序里引入新的名字和构造。举例来说,你可以使用声明来引入函数和方法,变量和常量,或者来定义
|
||||
新的命名好的枚举,结构,类和协议类型。你也可以使用一条声明来延长一个已经存在的命名好的类型的行为。或者在你的
|
||||
程序里引入在其他地方声明的符号。
|
||||
|
||||
在swift中,大多数声明在某种意义上讲也是执行或同事声明它们的初始化定义。这意味着,因为协议和他们的成员不匹配,
|
||||
大多数协议成员需要单独的声明。为了方便起见,也因为这些区别在swift里不是很重要,声明语句同时包含了声明和定义。
|
||||
|
||||
>GRAMMAR OF A DECLARATION
|
||||
|
||||
>declaration → import-declaration
|
||||
|
||||
>declaration → constant-declaration
|
||||
|
||||
>declaration → variable-declaration
|
||||
|
||||
>declaration → typealias-declaration
|
||||
|
||||
>declaration → function-declaration
|
||||
|
||||
>declaration → enum-declaration
|
||||
|
||||
>declaration → struct-declaration
|
||||
|
||||
>declaration → class-declaration
|
||||
|
||||
>declaration → protocol-declaration
|
||||
|
||||
> declaration → initializer-declaration
|
||||
|
||||
>declaration → deinitializer-declaration
|
||||
|
||||
> declaration → extension-declaration
|
||||
|
||||
> declaration → subscript-declaration
|
||||
|
||||
>declaration → operator-declaration
|
||||
|
||||
>declarations → declarationdeclarationsopt
|
||||
|
||||
>declaration-specifiers → declaration-specifierdeclaration-specifiersopt
|
||||
|
||||
>declaration-specifier → class | mutating | nonmutating | override | static | unowned |
|
||||
|
||||
<a name="module_scope"></a>
|
||||
##模块范围
|
||||
|
||||
模块范围定义了对模块中其他源文件可见的代码。(注:待改进)在swift的源文件中,最高级别的代码由零个或多个语句,
|
||||
声明和表达组成。变量,常量和其他的声明语句在一个源文件的最顶级被声明,使得他们对同一模块中的每个源文件都是可见的。
|
||||
|
||||
>GRAMMAR OF A TOP-LEVEL DECLARATION
|
||||
|
||||
>top-level-declaration → statements opt
|
||||
|
||||
<a name="code_blocks"></a>
|
||||
##代码块
|
||||
|
||||
代码块用来将一些声明和控制结构的语句组织在一起。它有如下的形式:
|
||||
|
||||
{
|
||||
`statements`
|
||||
}
|
||||
|
||||
代码块中的语句包括声明,表达式和各种其他类型的语句,它们按照在源码中的出现顺序被依次执行。
|
||||
|
||||
>GRAMMAR OF A CODE BLOCK
|
||||
|
||||
>code-block → statements opt
|
||||
|
||||
<a name="import_declaration"></a>
|
||||
##引入声明
|
||||
|
||||
引入声明使你可以使用在其他文件中声明的内容。引入语句的基本形式是引入整个代码模块;它由import关键字开始,后面
|
||||
紧跟一个模块名:
|
||||
|
||||
import module
|
||||
|
||||
你可以提供更多的细节来限制引入的符号,如声明一个特殊的子模块或者在一个模块或子模块中做特殊的声明。(待改进)
|
||||
当你使用了这些细节后,在当前的程序汇总只有引入的符号是可用的(并不是声明的整个模块)。
|
||||
|
||||
import import kind module.symbol name
|
||||
import module.submodule
|
||||
|
||||
>GRAMMAR OF AN IMPORT DECLARATION
|
||||
|
||||
>import-declaration → attributes opt import import-kind opt import-path
|
||||
>import-kind → typealias | struct | class | enum | protocol | var | func
|
||||
>import-path → import-path-identifier import-path-identifier.import-path
|
||||
>import-path-identifier → identifier operator
|
||||
|
||||
<a name="constant_declaration"></a>
|
||||
##常量声明
|
||||
|
||||
常量声明可以在你的程序里命名一个常量。常量以关键词let来声明,遵循如下的格式:
|
||||
|
||||
let constant name: type = expression
|
||||
|
||||
当常量的值被给定后,常量就将常量名称和表达式初始值不变的结合在了一起,而且不能更改。
|
||||
这意味着如果常量以类的形式被初始化,类本身的内容是可以改变的,但是常量和类之间的结合关系是不能改变的。
|
||||
当一个常量被声明为全局变量,它必须被给定一个初始值。当一个常量在类或者结构体中被声明时,他被认为是一个常量
|
||||
属性。常量并不是可计算的属性,因此不包含getters和setters。(译者注:getters和setters不知道怎么翻译,待改进)
|
||||
|
||||
如果常量名是一个元祖形式,元祖中的每一项初始化表达式中都要有对应的值
|
||||
|
||||
let (firstNumber, secondNumber) = (10, 42)
|
||||
|
||||
在上例中,firstNumber是一个值为10的常量,secnodeName是一个值为42的常量。所有常量都可以独立的使用:
|
||||
|
||||
1 println("The first number is \(firstNumber).")
|
||||
2 // prints "The first number is 10."
|
||||
3 println("The second number is \(secondNumber).")
|
||||
4 // prints "The second number is 42."
|
||||
|
||||
类型注释(:type)在常量声明中是一个可选项,它可以用来描述在类型接口(type inference)中找到的类型。
|
||||
|
||||
声明一个静态常量要使用关键字static。静态属性在类型属性(type propetries)中有介绍。
|
||||
|
||||
如果还想获得更多关于常量的信息或者想在使用中获得帮助,请查看常量和变量(constants and variables),
|
||||
存储属性(stored properties)等节。
|
||||
|
||||
>GRAMMAR OF A CONSTANT DECLARATION
|
||||
|
||||
>constant-declaration → attributes opt declaration-specifiers opt letpattern-initializer-list
|
||||
>pattern-initializer-list → pattern-initializer | pattern-initializer , pattern-initializer-list
|
||||
>pattern-initializer → pattern initializer opt
|
||||
>initializer → =expression
|
||||
|
||||
<a name="variable_declaration"></a>
|
||||
##变量声明
|
||||
|
||||
变量声明可以在你的程序里声明一个变量,它以关键字var来声明。根据声明变量类型和值的不同,如存储和计算
|
||||
变量和属性,存储变量和属性监视,和静态变量属性,有着不同的声明形式。(待改进)
|
||||
所使用的声明形式取决于变量所声明的范围和你打算声明的变量类型。
|
||||
|
||||
>注意:
|
||||
>
|
||||
你也可以在协议声明的上下文声明属性,详情参见类型属性声明。
|
||||
|
||||
###存储型变量和存储型属性
|
||||
|
||||
下面的形式声明了一个存储型变量或存储型变量属性
|
||||
|
||||
var variable name: type = expression
|
||||
|
||||
你可以在全局,函数内,或者在类和结构体的声明(context)中使用这种形式来声明一个变量。当变量以这种形式
|
||||
在全局或者一个函数内被声明时,它代表一个存储型变量。当他在类或者结构体中被声明时,他代表一个存储型变量属性。
|
||||
|
||||
构造器表达式可以被
|
||||
|
||||
和常量声明相比,如果变量名是一个元祖类型,元祖的每一项的名字都要和初始化表达式一致。
|
||||
|
||||
正如名字一样,存储型变量的值或存储型变量属性存储在内存中。
|
||||
|
||||
###计算型变量和计算型属性
|
||||
|
||||
如下形式声明一个一个存储型变量或存储型属性:
|
||||
|
||||
var variable name: type {
|
||||
get {
|
||||
statements
|
||||
}
|
||||
set(setter name) {
|
||||
statements
|
||||
}
|
||||
}
|
||||
|
||||
你可以在全局,函数体内或者类,结构体,枚举,扩展声明的上下文中使用这种形式的声明。
|
||||
当变量以这种形式在全局或者一个函数内被声明时,它代表一个计算型变量。当他在类,结构体,枚举,扩展声明的上下文
|
||||
中中被声明时,他代表一个计算型变量属性。
|
||||
|
||||
getter用来读取变量值,setter用来写入变量值。setter子句是可选择的,只有getter是必需的,你可以将这些语句
|
||||
都省略,只是简单的直接返回请求值,正如在只读计算属性(read-only computed properites)中描述的那样。
|
||||
但是如果你提供了一个setter语句,你也必需提供一个getter语句。
|
||||
|
||||
setter的名字和圆括号内的语句是可选的。如果你写了一个setter名,它就会作为setter的参数被使用。如果你不写setter名,
|
||||
setter的初始名为newValue,正如在seter声明速记(shorthand setter declaration)中提到的那样。
|
||||
|
||||
不像存储型变量和存储型属性那样,计算型属性和计算型变量的值不存储在内存中。
|
||||
|
||||
获得更多信息,查看更多关于计算型属性的例子,请查看计算型属性(computed properties)一节。
|
||||
|
||||
###存储型变量监视器和属性监视器
|
||||
|
||||
你可以用willset和didset监视器来声明一个存储型变量或属性。一个包含监视器的存储型变量或属性按如下的形式声明:
|
||||
|
||||
var variable name: type = expression {
|
||||
willSet(setter name) {
|
||||
statements
|
||||
}
|
||||
didSet(setter name {
|
||||
statements
|
||||
}
|
||||
}
|
||||
|
||||
你可以在全局,函数体内或者类,结构体,枚举,扩展声明的上下文中使用这种形式的声明。
|
||||
当变量以这种形式在全局或者一个函数内被声明时,监视器代表一个存储型变量监视器;
|
||||
当他在类,结构体,枚举,扩展声明的上下文中被声明时,监视器代表属性监视器。
|
||||
|
||||
你可以为适合的监视器添加任何存储型属性。你也可以通过重写子类属性的方式为适合的监视器添加任何继承的属性
|
||||
(无论是存储型还是计算型的),参见重写属性监视器(overriding properyt observers)。
|
||||
|
||||
初始化表达式在类或者结构体的声明中是可选的,但是在其他地方是必需的。无论在什么地方声明,
|
||||
所有包含监视器的变量声明都必须有类型注释(type annotation)。
|
||||
|
||||
当变量或属性的值被改变时,willset和didset监视器提供了一个监视方法(适当的回应)。
|
||||
监视器不会在变量或属性第一次初始化时不会被运行,他们只有在值被外部初始化语句改变时才会被运行。
|
||||
|
||||
willset监视器只有在变量或属性值被改变之前运行。新的值作为一个常量经过过willset监视器,因此不可以在
|
||||
willset语句中改变它。didset监视器在变量或属性值被改变后立即运行。和willset监视器相反,为了以防止你仍然
|
||||
需要获得旧的数据,旧变量值或者属性会经过didset监视器。这意味着,如果你在变量或属性自身的didiset监视器语句
|
||||
中设置了一个值,你设置的新值会取代刚刚在willset监视器中经过的那个值。
|
||||
|
||||
在willset和didset语句中,setter名和圆括号的语句是可选的。如果你写了一个setter名,它就会作为willset和didset的参数被使用。如果你不写setter名,
|
||||
willset监视器初始名为newvalue,didset监视器初始名为oldvalue。
|
||||
|
||||
当你提供一个willset语句时,didset语句是可选的。同样的,在你提供了一个didset语句时,willset语句是可选的。
|
||||
|
||||
获得更多信息,查看如何使用属性监视器的例子,请查看属性监视器(prpperty observers)一节。
|
||||
|
||||
###类和静态变量属性
|
||||
|
||||
class关键字用来声明类的计算型属性。static关键字用来声明类的静态变量属性。类和静态变量在类型属性(type properties)中有详细讨论。
|
||||
|
||||
>GRAMMAR OF A VARIABLE DECLARATION
|
||||
|
||||
>variable-declaration → variable-declaration-headpattern-initializer-list
|
||||
|
||||
>variable-declaration → variable-declaration-head variable-name type-annotation code-block
|
||||
|
||||
>variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-block
|
||||
|
||||
>variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block
|
||||
|
||||
> variable-declaration → variable-declaration-head variable-name type-annotationinitializer opt willSet-didSet-block
|
||||
|
||||
>variable-declaration-head → attributes opt declaration-specifiers opt var
|
||||
|
||||
>variable-name → identifier
|
||||
|
||||
>getter-setter-block → {getter-clause setter-clause opt}
|
||||
|
||||
>getter-setter-block → {setter-clause getter-clause}
|
||||
|
||||
>getter-clause → attributes optgetcode-block
|
||||
|
||||
>setter-clause → attributes opt set setter-name opt code-block
|
||||
|
||||
>setter-name → (identifier)
|
||||
|
||||
>getter-setter-keyword-block → {getter-keyword-clause setter-keyword-clause opt}
|
||||
|
||||
>getter-setter-keyword-block → {setter-keyword-clause getter-keyword-clause}
|
||||
|
||||
>getter-keyword-clause → attributes opt get
|
||||
|
||||
>setter-keyword-clause → attributes opt set
|
||||
|
||||
>willSet-didSet-block → {willSet-clause didSet-clause opt}
|
||||
|
||||
>willSet-didSet-block → {didSet-clause willSet-clause}
|
||||
|
||||
>willSet-clause → attributes opt willSet setter-name opt code-block
|
||||
|
||||
>didSet-clause → attributes opt didSet setter-name opt code-block
|
||||
|
||||
<a name="type_alias_declaration"></a>
|
||||
##类型的别名声明
|
||||
|
||||
类型别名的声明可以在你的程序里为一个已存在的类型声明一个别名。类型的别名声明以关键字typealias开始,遵循如下的
|
||||
形式:
|
||||
|
||||
typealias name = existing type
|
||||
|
||||
当一个类型被别名被声明后,你可以在你程序的任何地方使用别名来代替已存在的类型。已存在的类型可以是已经被命名的
|
||||
类型或者是混合类型。类型的别名不产生新的类型,它只是简单的和已存在的类型做名称替换。
|
||||
|
||||
查看更多Protocol Associated Type Declaration.
|
||||
|
||||
>GRAMMAR OF A TYPE ALIAS DECLARATION
|
||||
|
||||
> typealias-declaration → typealias-head typealias-assignment
|
||||
> typealias-head → typealias typealias-name
|
||||
> typealias-name → identifier
|
||||
> typealias-assignment → =type
|
||||
|
||||
<a name="function_declaration"></a>
|
||||
##函数声明
|
||||
|
||||
你可以使用函数声明在你的程序里引入新的函数。函数可以在类的上下文,结构体,枚举,或者作为方法的协议中被声明。
|
||||
函数声明使用关键字func,遵循如下的形式:
|
||||
|
||||
func function name(parameters) -> return type {
|
||||
statements
|
||||
}
|
||||
|
||||
如果函数不返回任何值,返回类型可以被忽略,如下所示:
|
||||
|
||||
func function name(parameters) {
|
||||
statements
|
||||
}
|
||||
|
||||
每个参数的类型都要标明,它们不能被推断出来。初始时函数的参数是常值。在这些参数前面添加var使它们成为变量,
|
||||
作用域内任何对变量的改变只在函数体内有效,或者用inout使的这些改变可以在调用域内生效。
|
||||
更多关于in-out参数的讨论,参见in-out参数(in-out parameters)
|
||||
|
||||
函数可以使用元组类型作为返回值来返回多个变量。
|
||||
|
||||
函数定义可以出现在另一个函数声明内。这种函数被称作nested函数。更多关于nested函数的讨论,参见nestde functions。
|
||||
|
||||
###参数名
|
||||
|
||||
函数的参数是一个以逗号分隔的列表 。函数调用是的变量顺序必须和函数声明时的参数顺序一致。
|
||||
最简单的参数列表有着如下的形式:
|
||||
|
||||
parameter name: parameter type
|
||||
|
||||
对于函数参数来讲,参数名在函数体内被使用,而不是在函数调用时使用。对于方法参数,参数名在函数体内被使用,
|
||||
同时也在方法被调用时作为标签被使用。该方法的第一个参数名仅仅在函数体内被使用,就像函数的参数一样,举例来讲:
|
||||
|
||||
func f(x: Int, y: String) -> String {
|
||||
return y + String(x)
|
||||
}
|
||||
f(7, "hello") // x and y have no name
|
||||
|
||||
class C {
|
||||
func f(x: Int, y: String) -> String {
|
||||
return y + String(x)
|
||||
}
|
||||
}
|
||||
let c = C()
|
||||
c.f(7, y: "hello") // x没有名称,y有名称
|
||||
|
||||
你可以按如下的形式,重写参数名被使用的过程:
|
||||
|
||||
external parameter name local parameter name: parameter type
|
||||
#parameter name: parameter type
|
||||
_ local parameter name: parameter type
|
||||
|
||||
在本地参数前命名的第二名称(second name)使得参数有一个扩展名。且不同于本地的参数名。
|
||||
扩展参数名在函数被调用时必须被使用。对应的参数在方法或函数被调用时必须有扩展名 。
|
||||
|
||||
在参数名前所写的哈希符号(#)代表着这个参数名可以同时作为外部或本体参数名来使用。等同于书写两次本地参数名。
|
||||
在函数或方法调用时,与其对应的语句必须包含这个名字。
|
||||
|
||||
本地参数名前的强调字符(_)使参数在函数被调用时没有名称。在函数或方法调用时,与其对应的语句必须没有名字。
|
||||
|
||||
###特殊类型的参数
|
||||
|
||||
参数可以被忽略,值可以是变化的,并且提供一个初始值,这种方法有着如下的形式:
|
||||
|
||||
_ : <#parameter type#.
|
||||
parameter name: parameter type...
|
||||
parameter name: parameter type = default argument value
|
||||
|
||||
以强调符(_)命名的参数明确的在函数体内不能被访问。
|
||||
|
||||
一个以基础类型名的参数,如果紧跟着三个点(...),被理解为是可变参数。一个函数至多可以拥有一个可变参数,
|
||||
且必须是最后一个参数。可变参数被作为该基本类型名的数组来看待。举例来讲,可变参数int...被看做是int[]。
|
||||
查看可变参数的使用例子,详见可变参数(variadic parameters)一节。
|
||||
|
||||
在参数的类型后面有一个以等号(=)连接的表达式,这样的参数被看做有着给定表达式的初试值。如果参数在函数
|
||||
调用时被省略了,就会使用初始值。如果参数没有胜率,那么它在函数调用是必须有自己的名字.举例来讲,
|
||||
f()和f(x:7)都是只有一个变量x的函数的有效调用,但是f(7)是非法的,因为它提供了一个值而不是名称。
|
||||
|
||||
###特殊方法
|
||||
|
||||
以self修饰的枚举或结构体方法必须以mutating关键字作为函数声明头。
|
||||
|
||||
子类重写的方法必须以override关键字作为函数声明头。不用override关键字重写的方法,使用了override关键字
|
||||
却并没有重写父类方法都会报错。
|
||||
|
||||
和类型相关而不是和类型实例相关的方法必须在static声明的结构以或枚举内,亦或是以class关键字定义的类内。
|
||||
|
||||
###柯里化函数和方法
|
||||
|
||||
柯里化函数或方法有着如下的形式:
|
||||
|
||||
func function name(parameters)(parameters) -> return type {
|
||||
statements
|
||||
}
|
||||
|
||||
以这种形式定义的函数的返回值是另一个函数。举例来说,下面的两个声明时等价的:
|
||||
|
||||
func addTwoNumbers(a: Int)(b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
func addTwoNumbers(a: Int) -> (Int -> Int) {
|
||||
func addTheSecondNumber(b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
return addTheSecondNumber
|
||||
}
|
||||
|
||||
addTwoNumbers(4)(5) // Returns 9
|
||||
|
||||
多级柯里化应用如下
|
||||
|
||||
>GRAMMAR OF A FUNCTION DECLARATION
|
||||
|
||||
>function-declaration → function-head function-name generic-parameter-clause optfunction-signature function-body
|
||||
> function-head → attributes opt declaration-specifiers opt func
|
||||
> function-name → identifier operator
|
||||
>function-signature → parameter-clauses function-result opt
|
||||
> function-result → ->attributes opt type
|
||||
> function-body → code-block
|
||||
> parameter-clauses → parameter-clause parameter-clauses opt
|
||||
> parameter-clause → () (parameter-list...opt)
|
||||
> parameter-list → parameter parameter,parameter-list
|
||||
> parameter → inout opt let opt#optparameter-name local-parameter-name opt type-annotation default-argument-clause opt
|
||||
> parameter → inoutoptvar#optparameter-namelocal-parameter-name opt type-annotationdefault-argument-clause opt
|
||||
> parameter → attributes opt type
|
||||
> parameter-name → identifier _
|
||||
> local-parameter-name → identifier _
|
||||
> default-argument-clause → =expression:
|
||||
|
||||
<a name="enumeration_declaration"></a>
|
||||
##枚举声明
|
||||
|
||||
在你的程序里使用枚举声明来引入一个枚举类型。
|
||||
|
||||
枚举声明有两种基本的形式,使用关键字enum来声明。枚举声明体使用从零开始的变量——叫做枚举事件,和任意数量的
|
||||
声明,包括计算型属性,实例方法,静态方法,构造器,类型别名,甚至其他枚举,结构体,和类。枚举声明不能
|
||||
包含析构器或者协议声明。
|
||||
|
||||
不像类或者结构体。枚举类型并不提供隐式的初始构造器,所有构造器必须显式的声明。构造器可以委托枚举中的其他
|
||||
构造器,但是构造过程仅当构造器将一个枚举时间完成后才全部完成。
|
||||
|
||||
和结构体类似但是和类不同,枚举是值类型:枚举实例在赋予变量或常量时,或者被函数调用时被复制。
|
||||
更多关于值类型的信息,参见结构体和枚举都是值类型(Structures and Enumerations Are Value Types)一节。
|
||||
|
||||
你可以扩展枚举类型,正如在扩展名声明(Extension Declaration)中讨论的一样。
|
||||
|
||||
###任意事件类型的枚举
|
||||
|
||||
如下的形式声明了一个包含任意类型枚举时间的枚举变量
|
||||
|
||||
enum enumeration name {
|
||||
case enumeration case 1
|
||||
case enumeration case 2(associated value types)
|
||||
}
|
||||
|
||||
这种形式的枚举声明在其他语言中有时被叫做可识别联合(discrinminated)。
|
||||
|
||||
这种形式中,每一个事件块由关键字case开始,后面紧接着一个或多个以逗号分隔的枚举事件。每一个事件名必须是
|
||||
独一无二的。每一个事件也可以指定它所存储的指定类型的值,这些类型在关联值类型的元祖里被指定,立即书写在事件
|
||||
名后。获得更多关于关联值类型的信息和例子,请查看关联值(associated values)一节。
|
||||
|
||||
###使用原始事件值的枚举
|
||||
|
||||
以下的形式声明了一个包含相同基础类型的枚举事件的枚举:
|
||||
|
||||
enum enumeration name: raw value type {
|
||||
case enumeration case 1 = raw value 1
|
||||
case enumeration case 2 = raw value 2
|
||||
}
|
||||
|
||||
在这种形式中,每一个事件块由case关键字开始,后面紧接着一个或多个以逗号分隔的枚举事件。和第一种形式的枚举
|
||||
事件不同,这种形式的枚举事件包含一个同类型的基础值,叫做原始值(raw value)。这些值的类型在原始值类型(raw value type)
|
||||
中被指定,必须是字面上的整数,浮点数,字符或者字符串。
|
||||
|
||||
每一个事件必须有唯一的名字,必须有一个唯一的初始值。如果初始值类型被指定为int,则不必为事件显式的指定值,
|
||||
它们会隐式的被标为值0,1,2等。每一个没有被赋值的Int类型时间会隐式的赋予一个初始值,它们是自动递增的。
|
||||
|
||||
num ExampleEnum: Int {
|
||||
case A, B, C = 5, D
|
||||
}
|
||||
|
||||
在上面的例子中,ExampleEnum.A的值是0,ExampleEnum.B的值是。因为ExampleEnum.C的值被显式的设定为5,因此
|
||||
ExampleEnum.D的值会自动增长为6.
|
||||
|
||||
枚举事件的初始值可以调用方法roRaw获得,如ExampleEnum.B.toRaw()。你也可以通过调用fromRaw方法来使用初始值找到
|
||||
其对应的事件,并返回一个可选的事件。查看更多信息和获取初始值类型事件的信息,参阅初始值(raw values)。
|
||||
|
||||
###获得枚举事件
|
||||
|
||||
使用点(.)来引用枚举类型的事件,如 EnumerationType.EnumerationCase。当枚举类型可以上下文推断出时,你可以
|
||||
省略它(.仍然需要),参照枚举语法(Enumeration Syntax)和显式成员表达(Implicit Member Expression).
|
||||
|
||||
使用switch语句来检验枚举事件的值,正如使用switch语句匹配枚举值(Matching Enumeration Values with a Switch Statement)一节描述的那样。
|
||||
|
||||
枚举类型是模式匹配(pattern-matched)的,和其相反的是switch语句case块中枚举事件匹配,在枚举事件类型(Enumeration Case Pattern)中有描述。
|
||||
|
||||
>GRAMMAR OF AN ENUMERATION DECLARATION
|
||||
|
||||
> enum-declaration → attributesoptunion-style-enum attributesoptraw-value-style-enum
|
||||
> union-style-enum → enum-namegeneric-parameter-clauseopt{union-style-enum-membersopt}
|
||||
union-style-enum-members → union-style-enum-memberunion-style-enum-membersopt
|
||||
union-style-enum-member → declaration union-style-enum-case-clause
|
||||
union-style-enum-case-clause → attributesoptcaseunion-style-enum-case-list
|
||||
union-style-enum-case-list → union-style-enum-case union-style-enum-case,union-style-enum-case-list
|
||||
union-style-enum-case → enum-case-nametuple-typeopt
|
||||
enum-name → identifier
|
||||
enum-case-name → identifier
|
||||
raw-value-style-enum → enum-namegeneric-parameter-clauseopt:type-identifier{raw-value-style-enum-membersopt}
|
||||
raw-value-style-enum-members → raw-value-style-enum-memberraw-value-style-enum-membersopt
|
||||
raw-value-style-enum-member → declaration raw-value-style-enum-case-clause
|
||||
raw-value-style-enum-case-clause → attributesoptcaseraw-value-style-enum-case-list
|
||||
raw-value-style-enum-case-list → raw-value-style-enum-case raw-value-style-enum-case,raw-value-style-enum-case-list
|
||||
raw-value-style-enum-case → enum-case-nameraw-value-assignmentopt
|
||||
raw-value-assignment → =literal
|
||||
|
||||
<a name="structure_declaration"></a>
|
||||
##结构体声明
|
||||
|
||||
使用结构体声明可以在你的程序里引入一个结构体类型。结构体声明使用struct关键字,遵循如下的形式:
|
||||
|
||||
struct structure name: adopted protocols {
|
||||
declarations
|
||||
}
|
||||
|
||||
结构体内包含零或多个声明。这些声明可以包括存储型和计算型属性,静态属性,实例方法,静态方法,构造器,
|
||||
类型别名,甚至其他结构体,类,和枚举声明。结构体声明不能包含析构器或者协议声明。详细讨论和包含多种结构体
|
||||
声明的实例,参见类和结构体一节。
|
||||
|
||||
结构体可以包含任意数量的协议,但是不能继承自类,枚举或者其他结构体。
|
||||
|
||||
有三种方法可以创建一个声明过的结构体实例:
|
||||
|
||||
-调用结构体内声明的构造器,参照构造器(initializers)一节。
|
||||
|
||||
—如果没有声明构造器,调用结构体的逐个构造器,详情参见Memberwise Initializers for Structure Types.
|
||||
|
||||
—如果没有声明析构器,结构体的所有属性都有初始值,调用结构体的默认构造器,详情参见默认构造器(Default Initializers).
|
||||
|
||||
结构体的构造过程参见初始化(initiaization)一节。
|
||||
|
||||
结构体实例属性可以用点(.)来获得,详情参见获得属性(Accessing Properties)一节。
|
||||
|
||||
结构体是值类型;结构体的实例在被赋予变量或常量,被函数调用时被复制。获得关于值类型更多信息,参见
|
||||
结构体和枚举都是值类型(Structures and Enumerations Are Value Types)一节。
|
||||
|
||||
你可以使用扩展声明来扩展结构体类型的行为,参见扩展声明(Extension Declaration).
|
||||
|
||||
>GRAMMAR OF A STRUCTURE DECLARATION
|
||||
|
||||
> struct-declaration → attributesoptstructstruct-namegeneric-parameter-clauseopttype-inheritance-clauseoptstruct-body
|
||||
> struct-name → identifier
|
||||
> struct-body → {declarationsopt}
|
||||
|
||||
<a name="class_declaration"></a>
|
||||
##类声明
|
||||
|
||||
你可以在你的程序中使用类声明来引入一个类。类声明使用关键字class,遵循如下的形式:
|
||||
|
||||
class class name: superclass, adopted protocols {
|
||||
declarations
|
||||
}
|
||||
|
||||
一个类内包含零或多个声明。这些声明可以包括存储型和计算型属性,实例方法,类方法,构造器,单独的析构器方法,
|
||||
类型别名,甚至其他结构体,类,和枚举声明。类声明不能包含协议声明。详细讨论和包含多种类声明的实例,参见类和
|
||||
结构体一节。
|
||||
|
||||
一个类只能继承一个父类,超类,但是可以包含任意数量的协议。这些超类第一次在type-inheritance-clause出现,遵循任意协议。
|
||||
|
||||
正如在初始化声明(Initializer Declaration)谈及的那样,类可以有指定和方便的构造器。当你声明任一中构造器时,
|
||||
你可以使用requierd变量来标记构造器,要求任意子类来重写它。指定类的构造器必须初始化类所有的已声明的属性,
|
||||
它必须在子类构造器调用前被执行。
|
||||
|
||||
类可以重写属性,方法和它的超类的构造器。重写的方法和属性必须以override标注。
|
||||
|
||||
虽然超类的属性和方法声明可以被当前类继承,但是超类声明的指定构造器却不能。这意味着,如果当前类重写了超类
|
||||
的所有指定构造器,它就继承了超类的方便构造器。Swift的类并不是继承自一个全局基础类。
|
||||
|
||||
有两种方法来创建已声明的类的实例:
|
||||
|
||||
-调用类的一个构造器,参见构造器(initializers)。
|
||||
|
||||
-如果没有声明构造器,而且类的所有属性都被赋予了初始值,调用类的默认构造器,参见默认构造器(default initializers).
|
||||
|
||||
类实例属性可以用点(.)来获得,详情参见获得属性(Accessing Properties)一节。
|
||||
|
||||
类是引用类型;当被赋予常量或变量,函数调用时,类的实例是被引用,而不是复制。获得更多关于引用类型的信息,
|
||||
结构体和枚举都是值类型(Structures and Enumerations Are Value Types)一节。
|
||||
|
||||
你可以使用扩展声明来扩展类的行为,参见扩展声明(Extension Declaration).
|
||||
|
||||
> GRAMMAR OF A CLASS DECLARATION
|
||||
|
||||
> class-declaration → attributesoptclassclass-namegeneric-parameter-clauseopttype-inheritance-clauseoptclass-body
|
||||
> class-name → identifier
|
||||
> class-body → {declarationsopt}
|
||||
|
||||
<a name="protocol_declaration"></a>
|
||||
##协议声明(translated by 小一)
|
||||
|
||||
一个协议声明为你的程序引入一个命名了的协议类型。协议声明使用 `protocol` 关键词来进行声明并有下面这样的形式:
|
||||
|
||||
```javascript
|
||||
protocol protocol name: inherited protocols {
|
||||
protocol member declarations
|
||||
}
|
||||
```
|
||||
|
||||
协议的主体包含零或多个协议成员声明,这些成员描述了任何采用该协议必须满足的一致性要求。特别的,一个协议可以声明必须实现某些属性、方法、初始化程序及附属脚本的一致性类型。协议也可以声明专用种类的类型别名,叫做关联类型,它可以指定协议的不同声明之间的关系。协议成员声明会在下面的详情里进行讨论。
|
||||
|
||||
协议类型可以从很多其它协议那继承。当一个协议类型从其它协议那继承的时候,来自其它协议的所有要求就集合了,而且从当前协议继承的任何类型必须符合所有的这些要求。对于如何使用协议继承的例子,查看[协议继承](../chapter2/21_Protocols.html#protocol_inheritance)
|
||||
|
||||
> 注意:
|
||||
>
|
||||
你也可以使用协议合成类型集合多个协议的一致性要求,详情参见[协议合成类型](../chapter3/03_Types.html#protocol_composition_type)和[协议合成](../chapter2/21_Protocols.html#protocol_composition)
|
||||
|
||||
你可以通过采用在类型的扩展声明中的协议来为之前声明的类型添加协议一致性。在扩展中你必须实现所有采用协议的要求。如果该类型已经实现了所有的要求,你可以让这个扩展声明的主题留空。
|
||||
|
||||
默认地,符合某一个协议的类型必须实现所有声明在协议中的属性、方法和附属脚本。也就是说,你可以用`optional`属性标注这些协议成员声明以指定它们的一致性类型实现是可选的。`optional`属性仅仅可以用于使用`objc`属性标记过的协议。这样的结果就是仅仅类类型可以采用并符合包含可选成员要求的协议。更多关于如何使用`optional`属性的信息及如何访问可选协议成员的指导——比如当你不能肯定是否一致性的类型实现了它们——参见[可选协议要求](../chapter2/21_Protocols.html#optional_protocol_requirements)
|
||||
|
||||
为了限制协议的采用仅仅针对类类型,需要使用`class_protocol`属性标记整个协议声明。任意继承自标记有`class_protocol`属性协议的协议都可以智能地仅能被类类型采用。
|
||||
|
||||
>注意:
|
||||
>
|
||||
如果协议已经用`object`属性标记了,`class_protocol`属性就隐性地应用于该协议;没有必要再明确地使用`class_protocol`属性来标记该协议了。
|
||||
|
||||
协议是命名的类型,因此它们可以以另一个命名类型出现在你代码的所有地方,就像[协议类型](../chapter2/21_Protocols.html#protocols_as_types)里讨论的那样。然而你不能构造一个协议的实例,因为协议实际上不提供它们指定的要求的实现。
|
||||
|
||||
你可以使用协议来声明一个类的代理的方法或者应该实现的结构,就像[委托(代理)模式](../chapter2/21_Protocols.html#delegation)描述的那样。
|
||||
|
||||
>协议声明的语法
|
||||
protocol-declaration → attributesoptprotocolprotocol-nametype-inheritance-clauseoptprotocol-body
|
||||
protocol-name → identifier
|
||||
protocol-body → {protocol-member-declarationsopt}
|
||||
protocol-member-declaration → protocol-property-declaration
|
||||
protocol-member-declaration → protocol-method-declaration
|
||||
protocol-member-declaration → protocol-initializer-declaration
|
||||
protocol-member-declaration → protocol-subscript-declaration
|
||||
protocol-member-declaration → protocol-associated-type-declaration
|
||||
protocol-member-declarations → protocol-member-declarationprotocol-member-declarationsopt
|
||||
|
||||
<a name="protocol_property_declaration"></a>
|
||||
###协议属性声明
|
||||
|
||||
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议属性声明来实现一个属性。协议属性声明有一种特殊的类型声明形式:
|
||||
|
||||
```javascript
|
||||
var property name: type { get set }
|
||||
```
|
||||
|
||||
同其它协议成员声明一样,这些属性声明仅仅针对符合该协议的类型声明了`getter`和`setter`要求。结果就是你不需要在协议里它被声明的地方实现`getter`和`setter`。
|
||||
|
||||
`getter`和`setter`要求可以通过一致性类型以各种方式满足。如果属性声明包含`get`和`set`关键词,一致性类型就可以用可读写(实现了`getter`和`setter`)的存储型变量属性或计算型属性,但是属性不能以常量属性或只读计算型属性实现。如果属性声明仅仅包含`get`关键词的话,它可以作为任意类型的属性被实现。比如说实现了协议的属性要求的一致性类型,参见[属性要求](../chapter2/21_Protocols.html#property_requirements)
|
||||
|
||||
更多参见[变量声明](../chapter3/05_Declarations.html#variable_declaration)
|
||||
|
||||
>协议属性声明语法
|
||||
protocol-property-declaration → variable-declaration-headvariable-nametype-annotationgetter-setter-keyword-block
|
||||
|
||||
###协议方法声明
|
||||
|
||||
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议方法声明来实现一个方法.
|
||||
协议方法声明和函数方法声明有着相同的形式,包含如下两条规则:他们不包括函数体,你不能在类的声明内为他们的
|
||||
参数提供初始值.举例来说,符合的类型执行协议必需的方法。参见必需方法一节。
|
||||
|
||||
使用关键字class可以在协议声明中声明一个类或必需的静态方法。执行这些方法的类也用关键字class声明。
|
||||
相反的,执行这些方法的结构体必须以关键字static声明。如果你想使用扩展方法,在扩展类时使用class关键字,
|
||||
在扩展结构体时使用static关键字。
|
||||
|
||||
更多请参阅函数声明。
|
||||
|
||||
>GRAMMAR OF A PROTOCOL METHOD DECLARATION
|
||||
|
||||
>protocol-method-declaration → function-headfunction-namegeneric-parameter-clauseoptfunction-signature
|
||||
|
||||
###协议构造器声明
|
||||
|
||||
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议构造器声明来实现一个构造器。协议构造器声明
|
||||
除了不包含构造器体外,和构造器声明有着相同的形式,
|
||||
|
||||
更多请参阅构造器声明。
|
||||
|
||||
>GRAMMAR OF A PROTOCOL INITIALIZER DECLARATION
|
||||
|
||||
>protocol-initializer-declaration → initializer-headgeneric-parameter-clauseoptparameter-clause
|
||||
|
||||
###协议附属脚本声明
|
||||
|
||||
协议声明了一致性类型必须在协议声明的主体里通过引入一个协议附属脚本声明来实现一个附属脚本。协议属性声明
|
||||
对附属脚本声明有一个特殊的形式:
|
||||
|
||||
>subscript (parameters) -> return type { get set }
|
||||
|
||||
附属脚本声明只为和协议一致的类型声明了必需的最小数量的的getter和setter。如果附属脚本申明包含get和set关键字,
|
||||
一致的类型也必须有一个getter和setter语句。如果附属脚本声明值包含get关键字,一致的类型必须至少包含一个
|
||||
getter语句,可以选择是否包含setter语句。
|
||||
|
||||
更多参阅附属脚本声明。
|
||||
|
||||
>GRAMMAR OF A PROTOCOL SUBSCRIPT DECLARATION
|
||||
|
||||
>protocol-subscript-declaration → subscript-headsubscript-resultgetter-setter-keyword-block
|
||||
|
||||
###协议相关类型声明
|
||||
|
||||
协议声明相关类型使用关键字typealias。相关类型为作为协议声明的一部分的类型提供了一个别名。相关类型和参数
|
||||
语句中的类型参数很相似,但是它们在声明的协议中包含self关键字。在这些语句中,self指代和协议一致的可能的类型。
|
||||
获得更多信息和例子,查看相关类型或类型别名声明。
|
||||
|
||||
>GRAMMAR OF A PROTOCOL ASSOCIATED TYPE DECLARATION
|
||||
|
||||
>protocol-associated-type-declaration → typealias-headtype-inheritance-clauseopttypealias-assignmentopt
|
||||
|
||||
<a name="initializer_declaration"></a>
|
||||
##构造器声明
|
||||
|
||||
构造器声明会为程序内的类,结构体或枚举引入构造器。构造器使用关键字Init来声明,遵循两条基本形式。
|
||||
|
||||
结构体,枚举,类可以有任意数量的构造器,但是类的构造器的规则和行为是不一样的。不像结构体和枚举那样,类
|
||||
有两种结构体,designed initializers 和convenience initializers,参见构造器一节。
|
||||
|
||||
如下的形式声明了结构体,枚举和类的指定构造器:
|
||||
|
||||
init(parameters) {
|
||||
statements
|
||||
}
|
||||
|
||||
类的指定构造器将类的所有属性直接初始化。如果类有超类,它不能调用该类的其他构造器,它只能调用超类的一个
|
||||
指定构造器。如果该类从它的超类处继承了任何属性,这些属性在当前类内被赋值或修饰时,必须带哦用一个超类的
|
||||
指定构造器。
|
||||
|
||||
指定构造器可以在类声明的上下文中声明,因此它不能用扩展声明的方法加入一个类中。
|
||||
|
||||
结构体和枚举的构造器可以带哦用其他的已声明的构造器,来委托其中一个火全部进行初始化过程。
|
||||
|
||||
以关键字convenience来声明一个类的便利构造器:
|
||||
|
||||
convenience init(parameters) {
|
||||
statements
|
||||
}
|
||||
|
||||
便利构造器可以将初始化过程委托给另一个便利构造器或类的一个指定构造器。这意味着,类的初始化过程必须
|
||||
以一个将所有类属性完全初始化的指定构造器的调用作为结束。便利构造器不能调用超类的构造器。
|
||||
|
||||
你可以使用requierd关键字,将便利构造器和指定构造器标记为每个子类的构造器都必须拥有的。因为指定构造器
|
||||
不被子类继承,他们必须被立即执行。当子类直接执行所有超类的指定构造器(或使用便利构造器重写指定构造器)时,
|
||||
必需的便利构造器可以被隐式的执行,亦可以被继承。不像方法,附属脚本那样,你不需要为这些重写的构造器标注
|
||||
overrride关键字。
|
||||
|
||||
查看更多关于不同声明方法的构造器的例子,参阅构造过程一节。
|
||||
|
||||
>GRAMMAR OF AN INITIALIZER DECLARATION
|
||||
|
||||
>initializer-declaration → initializer-headgeneric-parameter-clauseoptparameter-clauseinitializer-body
|
||||
>initializer-head → attributesoptconvenienceoptinit
|
||||
>initializer-body → code-block
|
||||
|
||||
<a name="deinitializer_declaration"></a>
|
||||
##析构声明
|
||||
|
||||
析构声明为类声明了一个析构器。析构器没有参数,遵循如下的格式:
|
||||
|
||||
deinit {
|
||||
statements
|
||||
}
|
||||
|
||||
当类没有任何语句时将要被释放时,析构器会自动的被调用。析构器在类的声明体内只能被声明一次——但是不能在
|
||||
类的扩展声明内,每个类最多只能有一个。
|
||||
|
||||
子类继承了它的超类的析构器,在子类将要被释放时隐式的调用。子类在所有析构器被执行完毕前不会被释放。
|
||||
|
||||
析构器不会被直接调用。
|
||||
|
||||
查看例子和如何在类的声明中使用析构器,参见析构过程一节
|
||||
。
|
||||
|
||||
>GRAMMAR OF A DEINITIALIZER DECLARATION
|
||||
|
||||
>deinitializer-declaration → attributesoptdeinitcode-block
|
||||
|
||||
<a name="extension_declaration"></a>
|
||||
##扩展声明
|
||||
|
||||
扩展声明用于扩展一个现存的类,结构体,枚举的行为。扩展声明以关键字extension开始,遵循如下的规则:
|
||||
|
||||
extension type: adopted protocols {
|
||||
declarations
|
||||
}
|
||||
|
||||
一个扩展声明体包括零个或多个声明。这些声明可以包括计算型属性,计算型静态属性,实例方法,静态和类方法,构造器,
|
||||
附属脚本声明,甚至其他结构体,类,和枚举声明。扩展声明不能包含析构器,协议声明,存储型属性,属性监测器或其他
|
||||
的扩展属性。详细讨论和查看包含多种扩展声明的实例,参见扩展一节。
|
||||
|
||||
扩展声明可以向现存的类,结构体,枚举内添加一致的协议。扩展声明不能向一个类中添加继承的类,因此
|
||||
type-inheritance-clause是一个只包含协议列表的扩展声明。
|
||||
|
||||
属性,方法,现存类型的构造器不能被它们类型的扩展所重写。
|
||||
|
||||
扩展声明可以包含构造器声明,这意味着,如果你扩展的类型在其他模块中定义,构造器声明必须委托另一个在
|
||||
那个模块里声明的构造器来恰当的初始化。
|
||||
|
||||
>GRAMMAR OF AN EXTENSION DECLARATION
|
||||
|
||||
>extension-declaration → extensiontype-identifiertype-inheritance-clauseoptextension-body
|
||||
>extension-body → {declarationsopt}
|
||||
|
||||
<a name="subscript_declaration"></a>
|
||||
##附属脚本声明(translated by 林)
|
||||
|
||||
附属脚本用于向特定类型添加附属脚本支持,通常为访问集合,列表和序列的元素时提供语法便利。附属脚本声明使用关键字`subscript`,声明形式如下:
|
||||
> subscript (`parameter`) -> (return type){
|
||||
get{
|
||||
`statements`
|
||||
}
|
||||
set(`setter name`){
|
||||
`statements`
|
||||
}
|
||||
}
|
||||
附属脚本声明只能在类,结构体,枚举,扩展和协议声明的上下文进行声明。
|
||||
|
||||
_变量(parameters)_指定一个或多个用于在相关类型的附属脚本中访问元素的索引(例如,表达式`object[i]`中的`i`)。尽管用于元素访问的索引可以是任意类型的,但是每个变量必须包含一个用于指定每种索引类型的类型标注。_返回类型(return type)_指定被访问的元素的类型。
|
||||
|
||||
和计算性属性一样,附属脚本声明支持对访问元素的读写操作。getter用于读取值,setter用于写入值。setter子句是可选的,当仅需要一个getter子句时,可以将二者都忽略且直接返回请求的值即可。也就是说,如果使用了setter子句,就必须使用getter子句。
|
||||
|
||||
setter的名字和封闭的括号是可选的。如果使用了setter名称,它会被当做传给setter的变量的名称。如果不使用setter名称,那么传给setter的变量的名称默认是`value`。setter名称的类型必须与_返回类型(return type)_的类型相同。
|
||||
|
||||
可以在附属脚本声明的类型中,可以重载附属脚本,只要_变量(parameters)_或_返回类型(return type)_与先前的不同即可。此时,必须使用`override`关键字声明那个被覆盖的附属脚本。(注:好乱啊!到底是重载还是覆盖?!)
|
||||
|
||||
同样可以在协议声明的上下文中声明附属脚本,[Protocol Subscript Declaration](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-XID_619)中有所描述。
|
||||
|
||||
更多关于附属脚本和附属脚本声明的例子,请参考[Subscripts](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Subscripts.html#//apple_ref/doc/uid/TP40014097-CH16-XID_393)。
|
||||
|
||||
>GRAMMAR OF A SUBSCRIPT DECLARATION
|
||||
|
||||
>subscript-declaration → subscript-headsubscript-resultcode-block
|
||||
>subscript-declaration → subscript-headsubscript-resultgetter-setter-block
|
||||
>subscript-declaration → subscript-headsubscript-resultgetter-setter-keyword-block
|
||||
>subscript-head → attributesoptsubscriptparameter-clause
|
||||
>subscript-result → ->attributesopttype
|
||||
|
||||
<a name="operator_declaration"></a>
|
||||
##运算符声明(translated by 林)
|
||||
|
||||
运算符声明会向程序中引入中缀、前缀或后缀运算符,它使用上下文关键字`operator`声明。
|
||||
可以声明三种不同的缀性:中缀、前缀和后缀。操作符的缀性描述了操作符与它的操作数的相对位置。
|
||||
运算符声明有三种基本形式,每种缀性各一种。运算符的缀性通过在`operator`和运算符之间添加上下文关键字`infix`,`prefix`或`postfix`来指定。每种形式中,运算符的名字只能包含[Operators](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-XID_871)中定义的运算符字符。
|
||||
|
||||
下面的这种形式声明了一个新的中缀运算符:
|
||||
> operator infix `operator name`{
|
||||
precedence `precedence level`
|
||||
associativity `associativity`
|
||||
}
|
||||
|
||||
_中缀_运算符是二元运算符,它可以被置于两个操作数之间,比如表达式`1 + 2` 中的加法运算符(`+`)。
|
||||
|
||||
中缀运算符可以可选地指定优先级,结合性,或两者同时指定。
|
||||
|
||||
运算符的_优先级_可以指定在没有括号包围的情况下,运算符与它的操作数如何紧密绑定的。可以使用上下文关键字`precedence`并_优先级(precedence level)_一起来指定一个运算符的优先级。_优先级_可以是0到255之间的任何一个数字(十进制整数);与十进制整数字面量不同的是,它不可以包含任何下划线字符。尽管优先级是一个特定的数字,但它仅用作与另一个运算符比较(大小)。也就是说,一个操作数可以同时被两个运算符使用时,例如`2 + 3 * 5`,优先级更高的运算符将优先与操作数绑定。
|
||||
|
||||
运算符的_结合性_可以指定在没有括号包围的情况下,优先级相同的运算符以何种顺序被分组的。可以使用上下文关键字`associativity`并_结合性(associativity)_一起来指定一个运算符的结合性,其中_结合性_可以说是上下文关键字`left`,`right`或`none`中的任何一个。左结合运算符以从左到右的形式分组。例如,减法运算符(`-`)具有左结合性,因此`4 - 5 - 6`被以`(4 - 5) - 6`的形式分组,其结果为`-7`。
|
||||
右结合运算符以从右到左的形式分组,对于设置为`none`的非结合运算符,它们不以任何形式分组。具有相同优先级的非结合运算符,不可以互相邻接。例如,表达式`1 < 2 < 3`非法的。
|
||||
|
||||
声明时不指定任何优先级或结合性的中缀运算符,它们的优先级会被初始化为100,结合性被初始化为`none`。
|
||||
|
||||
下面的这种形式声明了一个新的前缀运算符:
|
||||
> operator prefix `operator name`{}
|
||||
|
||||
紧跟在操作数前边的_前缀运算符(prefix operator)_是一元运算符,例如表达式`++i`中的前缀递增运算符(`++`)。
|
||||
|
||||
前缀运算符的声明中不指定优先级。前缀运算符是非结合的。
|
||||
|
||||
下面的这种形式声明了一个新的后缀运算符:
|
||||
|
||||
> operator postfix `operator name`{}
|
||||
|
||||
紧跟在操作数后边的_后缀运算符(postfix operator)_是一元运算符,例如表达式`i++`中的前缀递增运算符(`++`)。
|
||||
|
||||
和前缀运算符一样,后缀运算符的声明中不指定优先级。后缀运算符是非结合的。
|
||||
|
||||
声明了一个新的运算符以后,需要声明一个跟这个运算符同名的函数来实现这个运算符。如何实现一个新的运算符,请参考[Custom Operators](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html#//apple_ref/doc/uid/TP40014097-CH27-XID_48)。
|
||||
|
||||
>GRAMMAR OF AN OPERATOR DECLARATION
|
||||
>
|
||||
>operator-declaration → prefix-operator-declaration postfix-operator-declaration >infix-operator-declaration
|
||||
>prefix-operator-declaration → operator prefix operator{}
|
||||
>postfix-operator-declaration → operator postfix operator{}
|
||||
>infix-operator-declaration → operatorinfixoperator{infix-operator-attributesopt}
|
||||
>infix-operator-attributes → precedence-clauseoptassociativity-clauseopt
|
||||
>precedence-clause → precedenceprecedence-level
|
||||
>precedence-level → Digit 0 through 255
|
||||
>associativity-clause → associativityassociativity
|
||||
>associativity → left right none
|
||||
|
||||
@ -1,6 +1,15 @@
|
||||
> 翻译:Hawstein
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 特性
|
||||
-----------------
|
||||
|
||||
本页内容包括:
|
||||
|
||||
- [声明特性](#declaration_attributes)
|
||||
- [类型特性](#type_attributes)
|
||||
|
||||
特性提供了关于声明和类型的更多信息。在Swift中有两类特性,用于修饰声明的以及用于修饰类型的。例如,`required`特性,当应用于一个类的指定或便利初始化器声明时,表明它的每个子类都必须实现那个初始化器。再比如`noreturn`特性,当应用于函数或方法类型时,表明该函数或方法不会返回到它的调用者。
|
||||
|
||||
通过以下方式指定一个特性:符号`@`后面跟特性名,如果包含参数,则把参数带上:
|
||||
@ -12,6 +21,7 @@
|
||||
|
||||
有些声明特性通过接收参数来指定特性的更多信息以及它是如何修饰一个特定的声明的。这些特性的参数写在小括号内,它们的格式由它们所属的特性来定义。
|
||||
|
||||
<a name="declaration_attributes"></a>
|
||||
## 声明特性
|
||||
|
||||
声明特性只能应用于声明。然而,你也可以将`noreturn`特性应用于函数或方法类型。
|
||||
@ -91,6 +101,7 @@ Interface Builder特性是Interface Builder用来与Xcode同步的声明特性
|
||||
|
||||
`IBOutlet`和`IBInspectable`用于修饰一个类的属性声明;`IBAction`特性用于修饰一个类的方法声明;`IBDesignable`用于修饰类的声明。
|
||||
|
||||
<a name="type_attributes"></a>
|
||||
## 类型特性
|
||||
|
||||
类型特性只能用于修饰类型。然而,你也可以用`noreturn`特性去修饰函数或方法声明。
|
||||
|
||||
@ -1,6 +1,20 @@
|
||||
> 翻译:honghaoz
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 模式(Patterns)
|
||||
-----------------
|
||||
|
||||
本页内容包括:
|
||||
|
||||
- [通配符模式(Wildcard Pattern)](#wildcard_pattern)
|
||||
- [标识符模式(Identifier Pattern)](#identifier_pattern)
|
||||
- [值绑定模式(Value-Binding Pattern)](#value-binding_pattern)
|
||||
- [元组模式(Tuple Pattern)](#tuple_pattern)
|
||||
- [枚举案例模式(Enumeration Case Pattern)](#enumeration_case_pattern)
|
||||
- [类型转换模式(Type-Casting Patterns)](#type-casting_patterns)
|
||||
- [表达式模式(Expression Pattern)](#expression_pattern)
|
||||
|
||||
模式(pattern)代表了单个值或者复合值的结构。例如,元组`(1, 2)`的结构是逗号分隔的,包含两个元素的列表。因为模式代表一种值的结构,而不是特定的某个值,你可以把模式和各种同类型的值匹配起来。比如,`(x, y)`可以匹配元组`(1, 2)`,以及任何含两个元素的元组。除了将模式与一个值匹配外,你可以从合成值中提取出部分或全部,然后分别把各个部分和一个常量或变量绑定起来。
|
||||
|
||||
在Swift中,模式出现在变量和常量的声明(在它们的左侧),`for-in`语句和`switch`语句(在他们的case标签)中。尽管任何模式都可以出现在`switch`语句的case标签中,但在其他情况下,只有通配符模式(wildcard pattern),标识符模式(identifier pattern)和包含这两种模式的模式才能出现。
|
||||
@ -8,21 +22,22 @@
|
||||
你可以为通配符模式(wildcard pattern),标识符模式(identifier pattern)和元组模式(tuple pattern)指定类型注释,用来限制这种模式只匹配某种类型的值。
|
||||
|
||||
> 模式的语法:
|
||||
>
|
||||
>
|
||||
> pattern → wildcard-patterntype-annotationopt
|
||||
>
|
||||
>
|
||||
> pattern → identifier-patterntype-annotationopt
|
||||
>
|
||||
>
|
||||
> pattern → value-binding-pattern
|
||||
>
|
||||
>
|
||||
> pattern → tuple-patterntype-annotationopt
|
||||
>
|
||||
>
|
||||
> pattern → enum-case-pattern
|
||||
>
|
||||
>
|
||||
> pattern → type-casting-pattern
|
||||
>
|
||||
>
|
||||
> pattern → expression-pattern
|
||||
|
||||
<a name="wildcard_pattern"></a>
|
||||
## 通配符模式(Wildcard Pattern)
|
||||
|
||||
通配符模式匹配并忽略任何值,包含一个下划线(_)。当你不关心被匹配的值时,可以使用此模式。例如,下面这段代码进行了`1...3`的循环,并忽略了每次循环的值:
|
||||
@ -32,23 +47,25 @@
|
||||
}
|
||||
|
||||
> 通配符模式的语法:
|
||||
>
|
||||
>
|
||||
> wildcard-pattern → _
|
||||
|
||||
<a name="identifier_pattern"></a>
|
||||
## 标识符模式(Identifier Pattern)
|
||||
|
||||
标识符模式匹配任何值,并将匹配的值和一个变量或常量绑定起来。例如,在下面的常量申明中,`someValue`是一个标识符模式,匹配了类型是`Int`的`42`。
|
||||
|
||||
let someValue = 42
|
||||
|
||||
|
||||
当匹配成功时,`42`被绑定(赋值)给常量`someValue`。
|
||||
|
||||
当一个变量或常量申明的左边是标识符模式时,此时,标识符模式是隐式的值绑定模式(value-binding pattern)。
|
||||
|
||||
> 标识符模式的语法:
|
||||
>
|
||||
>
|
||||
> identifier-pattern → identifier
|
||||
|
||||
<a name="value-binding_pattern"></a>
|
||||
## 值绑定模式(Value-Binding Pattern)
|
||||
|
||||
值绑定模式绑定匹配的值到一个变量或常量。当绑定匹配值给常量时,用关键字`let`,绑定给变量时,用关键之`var`。
|
||||
@ -62,13 +79,14 @@
|
||||
println("The point is at (\(x), \(y)).")
|
||||
}
|
||||
// prints "The point is at (3, 2).”
|
||||
|
||||
|
||||
在上面这个例子中,`let`将元组模式`(x, y)`分配到各个标识符模式。因为这种行为,`switch`语句中`case let (x, y):`和`case (let x, let y):`匹配的值是一样的。
|
||||
|
||||
> 值绑定模式的语法:
|
||||
>
|
||||
>
|
||||
> value-binding-pattern → var pattern | let pattern
|
||||
|
||||
<a name="tuple_pattern"></a>
|
||||
## 元组模式(Tuple Pattern)
|
||||
|
||||
元组模式是逗号分隔的列表,包含一个或多个模式,并包含在一对圆括号中。元组模式匹配相应元组类型的值。
|
||||
@ -88,15 +106,16 @@
|
||||
let a = 2 // a: Int = 2
|
||||
let (a) = 2 // a: Int = 2
|
||||
let (a): Int = 2 // a: Int = 2
|
||||
|
||||
|
||||
> 元组模式的语法:
|
||||
>
|
||||
>
|
||||
> tuple-pattern → (tuple-pattern-element-list opt)
|
||||
>
|
||||
>
|
||||
> tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element, tuple-pattern-element-list
|
||||
>
|
||||
>
|
||||
> tuple-pattern-element → pattern
|
||||
|
||||
<a name="enumeration_case_pattern"></a>
|
||||
## 枚举案例模式(Enumeration Case Pattern)
|
||||
|
||||
枚举案例模式匹配现有的枚举类型的某种案例。枚举案例模式仅在`switch`语句中的`case`标签中出现。
|
||||
@ -104,16 +123,17 @@
|
||||
如果你准备匹配的枚举案例有任何关联的值,则相应的枚举案例模式必须指定一个包含每个关联值元素的元组模式。关于使用`switch`语句来匹配包含关联值枚举案例的例子,请参阅`Associated Values`.
|
||||
|
||||
> 枚举案例模式的语法:
|
||||
>
|
||||
>
|
||||
> enum-case-pattern → type-identifier opt . enum-case-name tuple-pattern opt
|
||||
|
||||
<a name="type-casting_patterns"></a>
|
||||
## 类型转换模式(Type-Casting Patterns)
|
||||
|
||||
有两种类型转换模式,`is`模式和`as`模式。这两种模式均只出现在`switch`语句中的`case`标签中。`is`模式和`as`模式有以下形式:
|
||||
|
||||
is type
|
||||
pattern as type
|
||||
|
||||
|
||||
`is`模式匹配一个值,如果这个值的类型在运行时(runtime)和`is`模式右边的指定类型(或者那个类型的子类)是一致的。`is`模式和`is`操作符一样,他们都进行类型转换,但是抛弃了返回的类型。
|
||||
|
||||
`as`模式匹配一个值,如果这个值的类型在运行时(runtime)和`as`模式右边的指定类型(或者那个类型的子类)是一致的。一旦匹配成功,匹配的值的类型被转换成`as`模式左边指定的模式。
|
||||
@ -121,13 +141,14 @@
|
||||
关于使用`switch`语句来匹配`is`模式和`as`模式值的例子,请参阅`Type Casting for Any and AnyObject`。
|
||||
|
||||
> 类型转换模式的语法:
|
||||
>
|
||||
>
|
||||
> type-casting-pattern → is-pattern as-pattern
|
||||
>
|
||||
>
|
||||
> is-pattern → istype
|
||||
>
|
||||
>
|
||||
> as-pattern → patternastype
|
||||
|
||||
<a name="expression_pattern"></a>
|
||||
## 表达式模式(Expression Pattern)
|
||||
|
||||
表达式模式代表了一个表达式的值。这个模式只出现在`switch`语句中的`case`标签中。
|
||||
@ -162,6 +183,6 @@
|
||||
// prints "(1, 2) is near the origin.”
|
||||
|
||||
> 表达式模式的语法:
|
||||
>
|
||||
>
|
||||
> expression-pattern → expression
|
||||
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
> 翻译:fd5788
|
||||
|
||||
> 校对:yankuangshi
|
||||
|
||||
# 泛型参数
|
||||
---------
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,17 @@
|
||||
> 翻译:coverxit
|
||||
|
||||
> 校对:numbbbbb
|
||||
|
||||
# 语句
|
||||
-----------------
|
||||
|
||||
本页包含内容:
|
||||
|
||||
- [循环语句](#loop_statements)
|
||||
- [分支语句](#branch_statements)
|
||||
- [带标签的语句](#labeled_statement)
|
||||
- [控制传递语句](#control_transfer_statements)
|
||||
|
||||
在 Swift 中,有两种类型的语句:简单语句和控制流语句。简单语句是最常见的,用于构造表达式和声明。控制流语句则用于控制程序执行的流程,Swift 中有三种类型的控制流语句:循环语句、分支语句和控制传递语句。
|
||||
|
||||
循环语句用于重复执行代码块;分支语句用于执行满足特定条件的代码块;控制传递语句则用于修改代码的执行顺序。在稍后的叙述中,将会详细地介绍每一种类型的控制流语句。
|
||||
@ -23,6 +34,7 @@
|
||||
|
||||
> *statement* → [*statment*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/statement) [*statements*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/statements)**;** *opt*
|
||||
|
||||
<a name="loop_statements"></a>
|
||||
## 循环语句
|
||||
|
||||
取决于特定的循环条件,循环语句允许重复执行代码块。Swift 提供四种类型的循环语句:`for`语句、`for-in`语句、`while`语句和`do-while`语句。
|
||||
@ -44,7 +56,7 @@
|
||||
`for`语句允许在重复执行代码块的同时,递增一个计数器。
|
||||
|
||||
`for`语句的形式如下:
|
||||
|
||||
|
||||
```swift
|
||||
for `initialzation`; `condition`; `increment` {
|
||||
`statements`
|
||||
@ -77,7 +89,7 @@ for `initialzation`; `condition`; `increment` {
|
||||
`for-in`语句允许在重复执行代码块的同时,迭代集合(或遵循`Sequence`协议的任意类型)中的每一项。
|
||||
|
||||
`for-in`语句的形式如下:
|
||||
|
||||
|
||||
```swift
|
||||
for `item` in `collection` {
|
||||
`statements`
|
||||
@ -95,7 +107,7 @@ for `item` in `collection` {
|
||||
`while`语句允许重复执行代码块。
|
||||
|
||||
`while`语句的形式如下:
|
||||
|
||||
|
||||
```swift
|
||||
while `condition` {
|
||||
`statements`
|
||||
@ -124,7 +136,7 @@ while `condition` {
|
||||
`do-while`语句允许代码块被执行一次或多次。
|
||||
|
||||
`do-while`语句的形式如下:
|
||||
|
||||
|
||||
```swift
|
||||
do {
|
||||
`statements`
|
||||
@ -144,8 +156,9 @@ do {
|
||||
|
||||
> GRAMMAR OF A DO-WHILE STATEMENT
|
||||
|
||||
> *do-while-statement* → **do** [*code-block*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/code-block) **while** [*while-condition*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/while-condition)
|
||||
> *do-while-statement* → **do** [*code-block*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/code-block) **while** [*while-condition*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/while-condition)
|
||||
|
||||
<a name="branch_statements"></a>
|
||||
## 分支语句
|
||||
|
||||
取决于一个或者多个条件的值,分支语句允许程序执行指定部分的代码。显然,分支语句中条件的值将会决定如何分支以及执行哪一块代码。Swift 提供两种类型的分支语句:`if`语句和`switch`语句。
|
||||
@ -270,7 +283,8 @@ case let (x, y) where x == y:
|
||||
|
||||
> *guard-expression* → [*expression*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression)
|
||||
|
||||
## 带标签的语句
|
||||
<a name="labeled_statement"></a>
|
||||
<a name="control_transfer_statements"></a> 带标签的语句
|
||||
|
||||
你可以在循环语句或`switch`语句前面加上*标签*,它由标签名和紧随其后的冒号(:)组成。在`break`和`continue`后面跟上标签名可以显式地在循环语句或`switch`语句中更改控制流,把控制权传递给指定标签标记的语句。关于这两条语句用法,请参考[Break 语句](#break_statement)和[Continue 语句](#continue_statement)。
|
||||
|
||||
@ -286,6 +300,7 @@ case let (x, y) where x == y:
|
||||
|
||||
> *label-name* → [*identifier*](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier)
|
||||
|
||||
|
||||
## 控制传递语句
|
||||
|
||||
通过无条件地把控制权从一片代码传递到另一片代码,控制传递语句能够改变代码执行的顺序。Swift 提供四种类型的控制传递语句:`break`语句、`continue`语句、`fallthrough`语句和`return`语句。
|
||||
|
||||
Reference in New Issue
Block a user