Declarations -> 2.2
This commit is contained in:
@ -6,14 +6,24 @@
|
||||
> 翻译:[marsprince](https://github.com/marsprince) [Lenhoon](https://github.com/marsprince)[(微博)](http://www.weibo.com/lenhoon)
|
||||
> 校对:[numbbbbb](https://github.com/numbbbbb), [stanzhai](https://github.com/stanzhai)
|
||||
|
||||
|
||||
|
||||
> 2.0
|
||||
> 翻译+校对:[Lenhoon](https://github.com/Lenhoon),
|
||||
> [BridgeQ](https://github.com/WXGBridgeQ)
|
||||
|
||||
|
||||
|
||||
> 2.1
|
||||
> 翻译:[mmoaay](https://github.com/mmoaay), [shanks](http://codebuild.me)
|
||||
> 校对:[shanks](http://codebuild.me)
|
||||
|
||||
|
||||
|
||||
> 2.2
|
||||
> 翻译:[星夜暮晨](https://github.com/SemperIdem)
|
||||
> 校对:
|
||||
|
||||
本页包含内容:
|
||||
|
||||
- [顶级代码](#top-level_code)
|
||||
@ -56,12 +66,12 @@
|
||||
- [声明修饰符](#declaration_modifiers)
|
||||
- [访问控制级别](#access_control_levels)
|
||||
|
||||
声明可以在程序里引入新的名字或者构造。举例来说,可以使用声明来引入函数和方法,变量和常量,或者来定义新的命名的枚举,结构,类和协议类型。还可以使用声明来扩展一个已经存在的命名的类型的行为,或者在程序里引入在其它地方声明的符号。
|
||||
*声明 (declaration)* 用以向程序里引入新的名字或者构造。举例来说,可以使用声明来引入函数和方法,变量和常量,或者来定义新的命名枚举,结构,类和协议类型。还可以使用声明来扩展一个已经存在的命名的类型的行为,或者在程序里引入在其它地方声明的符号。
|
||||
|
||||
在 Swift 中,大多数声明在某种意义上讲也是定义,实现或初始化往往伴随着声明。这意味着,由于协议往往并不提供实现,大多数协议仅仅只是声明而已。为了方便起见,也因为这些区别在 Swift 中不是很重要,“声明”这个术语同时包含了声明和定义。
|
||||
在 Swift 中,大多数声明在某种意义上讲也是定义,实现或初始化往往伴随着声明。这意味着,由于协议往往并不提供实现,大多数协议仅仅只是声明而已。为了方便起见,也因为这些区别在 Swift 中不是很重要,*“声明”*这个术语同时包含了声明和定义。
|
||||
|
||||
> 声明语法
|
||||
<a name="declaration"></a>
|
||||
> <a name="declaration"></a>
|
||||
> *声明* → [*导入声明*](#import-declaration)
|
||||
> *声明* → [*常量声明*](#constant-declaration)
|
||||
> *声明* → [*变量声明*](#variable-declaration)
|
||||
@ -76,13 +86,13 @@
|
||||
> *声明* → [*扩展声明*](#extension-declaration)
|
||||
> *声明* → [*下标声明*](#subscript-declaration)
|
||||
> *声明* → [*运算符声明*](#operator-declaration)
|
||||
<a name="declarations"></a>
|
||||
> <a name="declarations"></a>
|
||||
> *多条声明* → [*声明*](#declaration) [*多条声明*](#declarations)<sub>可选</sub>
|
||||
|
||||
<a name="top-level_code"></a>
|
||||
## 顶级代码
|
||||
|
||||
Swift 的源文件中的顶级代码由零个或多个语句,声明和表达式组成。默认情况下,在一个源文件的顶层声明的变量,常量和其他命名的声明语句可以被同一模块中的每一个源文件中的代码访问。可以使用一个访问级别修饰符来标记声明,从而覆盖默认行为,请参阅 [访问控制级别](#access_control_levels)。
|
||||
Swift 的源文件中的顶级代码 (top-level code) 由零个或多个语句,声明和表达式组成。默认情况下,在一个源文件的顶层声明的变量,常量和其他命名的声明语句可以被同一模块中的每一个源文件中的代码访问。可以使用一个访问级别修饰符来标记声明,从而覆盖默认行为,请参阅 [访问控制级别](#access_control_levels)。
|
||||
|
||||
> 顶级声明语法
|
||||
> *顶级声明* → [*多条语句*](10_Statements.md#statements)<sub>可选</sub>
|
||||
@ -90,55 +100,59 @@ Swift 的源文件中的顶级代码由零个或多个语句,声明和表达
|
||||
<a name="code_blocks"></a>
|
||||
## 代码块
|
||||
|
||||
代码块可以将一些声明和控制结构组织在一起。它有如下的形式:
|
||||
*代码块 (code block)* 可以将一些声明和控制结构组织在一起。它有如下的形式:
|
||||
|
||||
```swift
|
||||
{
|
||||
语句
|
||||
<#语句#>
|
||||
}
|
||||
```
|
||||
|
||||
代码块中的语句包括声明,表达式和各种其他类型的语句,它们按照在源码中的出现顺序被依次执行。
|
||||
代码块中的*语句*包括声明,表达式和各种其他类型的语句,它们按照在源码中的出现顺序被依次执行。
|
||||
|
||||
> 代码块语法
|
||||
<a name="code-block"></a>
|
||||
> <a name="code-block"></a>
|
||||
> *代码块* → **{** [*多条语句*](10_Statements.md#statements)<sub>可选</sub> **}**
|
||||
|
||||
<a name="import_declaration"></a>
|
||||
## 导入声明
|
||||
|
||||
导入声明让你可以使用在其他文件中声明的内容。导入语句的基本形式是导入整个模块,它由 `import` 关键字开始,后面紧跟一个模块名:
|
||||
*导入声明 (import declaration)* 让你可以使用在其他文件中声明的内容。导入语句的基本形式是导入整个模块,它由 `import` 关键字开始,后面紧跟一个模块名:
|
||||
|
||||
> import `模块`
|
||||
```swift
|
||||
import <#模块#>
|
||||
```
|
||||
|
||||
可以对导入提供更细致的控制,如指定一个特殊的子模块或者指定一个模块或子模块中的某个声明。提供了这些限制后,在当前作用域中,只有导入的符号是可用的,而不是整个模块。
|
||||
|
||||
> import `导入类型` `模块`.`符号名`
|
||||
> import `模块`.`子模块`
|
||||
```swift
|
||||
import <#导入类型#> <#模块#>.<#符号名#>
|
||||
import <#模块#>.<#子模块#>
|
||||
```
|
||||
|
||||
<a name="grammer_of_an_import_declaration"></a>
|
||||
> 导入声明语法
|
||||
<a name="import-declaration"></a>
|
||||
> <a name="import-declaration"></a>
|
||||
> *导入声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **import** [*导入类型*](#import-kind)<sub>可选</sub> [*导入路径*](#import-path)
|
||||
<a name="import-kind"></a>
|
||||
> <a name="import-kind"></a>
|
||||
> *导入类型* → **typealias** | **struct** | **class** | **enum** | **protocol** | **var** | **func**
|
||||
<a name="import-path"></a>
|
||||
> <a name="import-path"></a>
|
||||
> *导入路径* → [*导入路径标识符*](#import-path-identifier) | [*导入路径标识符*](#import-path-identifier) **.** [*导入路径*](#import-path)
|
||||
<a name="import-path-identifier"></a>
|
||||
> <a name="import-path-identifier"></a>
|
||||
> *导入路径标识符* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
|
||||
<a name="constant_declaration"></a>
|
||||
## 常量声明
|
||||
|
||||
常量声明可以在程序中命名一个常量。常量以关键字 `let` 来声明,遵循如下的格式:
|
||||
*常量声明 (constant declaration)* 可以在程序中命名一个常量。常量以关键字 `let` 来声明,遵循如下的格式:
|
||||
|
||||
> let `常量名称`: `类型` = `表达式`
|
||||
```swift
|
||||
let <#常量名称#>: <#类型#> = <#表达式#>
|
||||
```
|
||||
|
||||
当常量的值被给定后,常量就将常量名称和表达式的值绑定在了一起,不能更改。
|
||||
常量声明在*常量名称*和初始化*表达式*的值之间,定义了一种不可变的绑定关系;当常量的值被设定之后,它就无法被更改。这意味着,如果常量以类对象来初始化,对象本身的内容是可以改变的,但是常量和该对象之间的结合关系是不能改变的。
|
||||
|
||||
这意味着,如果常量以类对象来初始化,对象本身的内容是可以改变的,但是常量和该对象之间的结合关系是不能改变的。
|
||||
|
||||
当一个常量被声明为全局变量,它必须被给定一个初始值。在类或者结构体中声明一个常量时,它被认为是一个常量属性。常量声明不能是计算型属性,因此也没有存取方法。
|
||||
当一个常量被声明为全局变量,它必须被给定一个初始值。在类或者结构体中声明一个常量时,它被认为是一个*常量属性 (constant property)*。常量声明不能是计算型属性,因此也没有存取方法。
|
||||
|
||||
如果常量名称是元组形式,元组中的每一项的名称会和对应的初始化表达式的值绑定。
|
||||
|
||||
@ -155,7 +169,7 @@ print("The second number is \(secondNumber).")
|
||||
// 打印 “The second number is 42.”
|
||||
```
|
||||
|
||||
当常量名称的类型可以被推断出时,类型标注在常量声明中是一个可选项,正如 [类型推断](03_Types.md#type_inference) 中所描述的。
|
||||
当常量名称的类型 (`:` *type*) 可以被推断出时,类型标注在常量声明中是一个可选项,正如 [类型推断](03_Types.md#type_inference) 中所描述的。
|
||||
|
||||
声明一个常量类型属性要使用 `static` 声明修饰符。类型属性在 [类型属性](../chapter2/10_Properties.md#type_properties)中有介绍。
|
||||
|
||||
@ -163,19 +177,19 @@ print("The second number is \(secondNumber).")
|
||||
|
||||
<a name="grammer_of_a_constant_declaration"></a>
|
||||
> 常量声明语法
|
||||
<a name="constant-declaration"></a>
|
||||
> <a name="constant-declaration"></a>
|
||||
> *常量声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **let** [*模式构造器列表*](pattern-initializer-list)
|
||||
<a name="pattern-initializer-list"></a>
|
||||
> <a name="pattern-initializer-list"></a>
|
||||
> *模式构造器列表* → [*模式构造器*](#pattern-initializer) | [*模式构造器*](#pattern-initializer) **,** [*模式构造器列表*](#pattern-initializer-list)
|
||||
<a name="pattern-initializer"></a>
|
||||
> <a name="pattern-initializer"></a>
|
||||
> *模式构造器* → [*模式*](07_Patterns.md#pattern) [*构造器*](#initializer)<sub>可选</sub>
|
||||
<a name="initializer"></a>
|
||||
> <a name="initializer"></a>
|
||||
> *构造器* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="variable_declaration"></a>
|
||||
## 变量声明
|
||||
|
||||
变量声明可以在程序中声明一个变量,它以关键字 `var` 来声明。
|
||||
*变量声明 (variable declaration)* 可以在程序中声明一个变量,它以关键字 `var` 来声明。
|
||||
|
||||
变量声明有几种不同的形式,可以声明不同种类的命名值和可变值,如存储型和计算型变量和属性,属性观察器,以及静态变量属性。所使用的声明形式取决于变量声明的适用范围和打算声明的变量类型。
|
||||
|
||||
@ -189,11 +203,13 @@ print("The second number is \(secondNumber).")
|
||||
|
||||
使用如下形式声明一个存储型变量或存储型变量属性:
|
||||
|
||||
> var `变量名称`: `类型` = `表达式`
|
||||
```swift
|
||||
var <#变量名称#>: <#类型#> = <#表达式#>
|
||||
```
|
||||
|
||||
可以在全局范围,函数内部,或者在类和结构体的声明中使用这种形式来声明一个变量。当变量以这种形式在全局范围或者函数内部被声明时,它代表一个存储型变量。当它在类或者结构体中被声明时,它代表一个存储型变量属性。
|
||||
可以在全局范围,函数内部,或者在类和结构体的声明中使用这种形式来声明一个变量。当变量以这种形式在全局范围或者函数内部被声明时,它代表一个存储型变量。当它在类或者结构体中被声明时,它代表一个*存储型变量属性 (stored variable property)*。
|
||||
|
||||
用于初始化的表达式不可以在协议的声明中出现,在其他情况下,该表达式是可选的。如果没有初始化表达式,那么变量声明必须包含类型标注。
|
||||
用于初始化的表达式不可以在协议的声明中出现,在其他情况下,该表达式是可选的。如果没有初始化表达式,那么变量声明必须包含类型标注 (`:` *type*)。
|
||||
|
||||
对于常量的声明,如果变量名称是一个元组,元组中每一项的名称都要和初始化表达式中的相应值绑定。
|
||||
|
||||
@ -205,17 +221,17 @@ print("The second number is \(secondNumber).")
|
||||
使用如下形式声明一个计算型变量或计算型属性:
|
||||
|
||||
```swift
|
||||
var 变量名称: 类型 {
|
||||
var <#变量名称#>: <#类型#> {
|
||||
get {
|
||||
语句
|
||||
<#语句#>
|
||||
}
|
||||
set(setter 名称) {
|
||||
语句
|
||||
set(<#setter 名称#>) {
|
||||
<#语句#>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以在全局范围,函数内部,以及类,结构体,枚举,扩展声明的上下文中使用这种形式的声明。当变量以这种形式在全局范围或者函数内部被声明时,它代表一个计算型变量。当它在类,结构体,枚举,扩展声明的上下文中被声明时,它代表一个计算型属性。
|
||||
可以在全局范围,函数内部,以及类,结构体,枚举,扩展声明的上下文中使用这种形式的声明。当变量以这种形式在全局范围或者函数内部被声明时,它代表一个计算型变量。当它在类,结构体,枚举,扩展声明的上下文中被声明时,它代表一个*计算型属性 (computed property)*。
|
||||
|
||||
getter 用来读取变量值,setter 用来写入变量值。setter 子句是可选的,getter 子句是必须的。也可以将这些子句都省略,直接返回请求的值,正如在 [只读计算型属性](../chapter2/10_Properties.md#computed_properties) 中描述的那样。但是如果提供了一个 setter 子句,也必须提供一个 getter 子句。
|
||||
|
||||
@ -231,12 +247,12 @@ getter 用来读取变量值,setter 用来写入变量值。setter 子句是
|
||||
可以在声明存储型变量或属性时提供 `willSet` 和 `didSet` 观察器。一个包含观察器的存储型变量或属性以如下形式声明:
|
||||
|
||||
```swift
|
||||
var 变量名称: 类型 = 表达式 {
|
||||
willSet(setter 名称) {
|
||||
语句
|
||||
var <#变量名称#>: <#类型#> = <#表达式#> {
|
||||
willSet(<#setter 名称#>) {
|
||||
<#语句#>
|
||||
}
|
||||
didSet(setter 名称) {
|
||||
语句
|
||||
didSet(<#setter 名称#>) {
|
||||
<#语句#>
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -279,89 +295,93 @@ var 变量名称: 类型 = 表达式 {
|
||||
|
||||
<a name="variable-declaration-head"></a>
|
||||
> *变量声明头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **var**
|
||||
<a name="variable-name"></a>
|
||||
> <a name="variable-name"></a>
|
||||
> *变量名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="getter-setter-block"></a>
|
||||
> *getter-setter 代码块* → [*代码块*](#code-block)
|
||||
> *getter-setter 代码块* → **{** [*getter子句*](#getter-clause) [*setter子句*](#setter-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 代码块* → **{** [*setter子句*](#setter-clause) [*getter子句*](#getter-clause) **}**
|
||||
<a name="getter-clause"></a>
|
||||
> <a name="getter-clause"></a>
|
||||
> *getter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get** [*代码块*](#code-block)
|
||||
<a name="setter-clause"></a>
|
||||
> <a name="setter-clause"></a>
|
||||
> *setter 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
<a name="setter-name"></a>
|
||||
> <a name="setter-name"></a>
|
||||
> *setter 名称* → **(** [*标识符*](02_Lexical_Structure.md#identifier) **)**
|
||||
|
||||
<a name="getter-setter-keyword-block"></a>
|
||||
> *getter-setter 关键字代码块* → **{** [*getter关键字子句*](#getter-keyword-clause) [*setter关键字子句*](#setter-keyword-clause)<sub>可选</sub> **}**
|
||||
> *getter-setter 关键字代码块* → **{** [*setter关键字子句*](#setter-keyword-clause) [*getter关键字子句*](#getter-keyword-clause) **}**
|
||||
<a name="getter-keyword-clause"></a>
|
||||
> <a name="getter-keyword-clause"></a>
|
||||
> *getter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **get**
|
||||
<a name="setter-keyword-clause"></a>
|
||||
> <a name="setter-keyword-clause"></a>
|
||||
> *setter 关键字子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **set**
|
||||
|
||||
<a name="willSet-didSet-block"></a>
|
||||
> *willSet-didSet 代码块* → **{** [*willSet子句*](#willSet-clause) [*didSet子句*](#didSet-clause)<sub>可选</sub> **}**
|
||||
> *willSet-didSet 代码块* → **{** [*didSet子句*](#didSet-clause) [*willSet子句*](#willSet-clause)<sub>可选</sub> **}**
|
||||
<a name="willSet-clause"></a>
|
||||
> <a name="willSet-clause"></a>
|
||||
> *willSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **willSet** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
<a name="didSet-clause"></a>
|
||||
> <a name="didSet-clause"></a>
|
||||
> *didSet 子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **didSet** [*setter名称*](#setter-name)<sub>可选</sub> [*代码块*](#code-block)
|
||||
|
||||
<a name="type_alias_declaration"></a>
|
||||
## 类型别名声明
|
||||
|
||||
类型别名声明可以在程序中为一个现存类型声明一个别名。类型别名声明语句使用关键字 `typealias` 声明,遵循如下的形式:
|
||||
*类型别名 (type alias)* 声明可以在程序中为一个现存类型声明一个别名。类型别名声明语句使用关键字 `typealias` 声明,遵循如下的形式:
|
||||
|
||||
> `类型别名` = `现存类型`
|
||||
```swift
|
||||
typealias <#类型别名#> = <#现存类型#>
|
||||
```
|
||||
|
||||
当声明一个类型的别名后,可以在程序的任何地方使用别名来代替现存类型。现存类型可以是命名类型或者混合类型。类型别名不产生新的类型,它只是可以使用别名来引用现存类型。
|
||||
当声明一个类型的别名后,可以在程序的任何地方使用*别名*来代替*现存类型*。*现存类型*可以是命名类型或者混合类型。类型别名不产生新的类型,它只是可以使用别名来引用现存类型。
|
||||
|
||||
另请参阅 [协议关联类型声明](#protocol_associated_type_declaration)。
|
||||
|
||||
<a name="grammer_of_a_type_alias_declaration"></a>
|
||||
> 类型别名声明语法
|
||||
<a name="typealias-declaration"></a>
|
||||
> <a name="typealias-declaration"></a>
|
||||
> *类型别名声明* → [*类型别名头*](#typealias-head) [*类型别名赋值*](#typealias-assignment)
|
||||
<a name="typealias-head"></a>
|
||||
> <a name="typealias-head"></a>
|
||||
> *类型别名头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier)<sub>可选</sub> **typealias** [*类型别名名称*](#typealias-name)
|
||||
<a name="typealias-name"></a>
|
||||
> <a name="typealias-name"></a>
|
||||
> *类型别名名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="typealias-assignment"></a>
|
||||
> <a name="typealias-assignment"></a>
|
||||
> *类型别名赋值* → **=** [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="function_declaration"></a>
|
||||
## 函数声明
|
||||
|
||||
使用函数声明在程序中引入新的函数或者方法。当一个函数被声明在类,结构体,枚举,或者协议的上下文中,会作为一个方法。函数声明使用关键字 `func`,遵循如下的形式:
|
||||
使用*函数声明 (function declaration)* 在程序中引入新的函数或者方法。当一个函数被声明在类,结构体,枚举,或者协议的上下文中,会作为一个方法。函数声明使用关键字 `func`,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) -> 返回类型 {
|
||||
语句
|
||||
func <#函数名称#>(<#参数列表#>) -> <#返回类型#> {
|
||||
<#语句#>
|
||||
}
|
||||
```
|
||||
|
||||
如果函数返回 `Void` 类型,返回类型可以省略,如下所示:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) {
|
||||
语句
|
||||
func <#函数名称#>(<#参数列表#>) {
|
||||
<#语句#>
|
||||
}
|
||||
```
|
||||
|
||||
每个参数的类型都要标明,它们不能被推断出来。虽然函数的参数默认是常量,也可以在参数名前添加 `let` 来强调这一行为。在参数名前面添加 `var` 则会使它们成为变量,作用域内任何对变量的改变只在函数体内有效,或者用 `inout` 使这些改变可以在调用域内生效。更多关于 `inout` 参数的讨论,请参阅 [输入输出参数](#in-out_parameters)。
|
||||
每个参数的类型都要标明,它们不能被推断出来。虽然函数的参数默认是常量,也可以在参数名前添加 `let` 来强调这一行为。如果您在某个参数名前面加上了 `inout`,那么这个参数就可以在这个函数作用域当中被修改。更多关于 `inout` 参数的讨论,请参阅 [输入输出参数](#in-out_parameters)。
|
||||
|
||||
函数可以使用元组类型作为返回类型来返回多个值。
|
||||
|
||||
函数定义可以出现在另一个函数声明内。这种函数被称作嵌套函数。更多关于嵌套函数的讨论,请参阅 [嵌套函数](../chapter2/06_Functions.md#Nested_Functions)。
|
||||
函数定义可以出现在另一个函数声明内。这种函数被称作*嵌套函数 (nested function)*。更多关于嵌套函数的讨论,请参阅 [嵌套函数](../chapter2/06_Functions.md#Nested_Functions)。
|
||||
|
||||
<a name="parameter_names"></a>
|
||||
### 参数名
|
||||
|
||||
函数的参数列表由一个或多个函数参数组成,参数间以逗号分隔。函数调用时的参数顺序必须和函数声明时的参数顺序一致。最简单的参数列表有着如下的形式:
|
||||
|
||||
> `参数名称`: `参数类型`
|
||||
```swift
|
||||
<#参数名称#>: <#参数类型#>
|
||||
```
|
||||
|
||||
一个参数有一个内部名称,这个内部名称可以在函数体内被使用。同样也可以作为外部名称,当调用函数时这个外部名称被作为实参的标签来使用。默认情况下,第一个参数的外部名称省略不写,第二个和之后的参数使用它们的内部名称作为它们的外部名称。例如:
|
||||
|
||||
@ -372,8 +392,10 @@ f(1, y: 2) // 参数 y 有标签,参数 x 则没有
|
||||
|
||||
可以按照如下两种形式之一,重写参数名称的默认行为:
|
||||
|
||||
> `外部参数名称` `内部参数名称`: `参数类型`
|
||||
> _ `内部参数名称`: `参数类型`
|
||||
```swift
|
||||
<#外部参数名称#> <#内部参数名称#>: <#参数类型#>
|
||||
_ <#内部参数名称#>: <#参数类型#>
|
||||
```
|
||||
|
||||
在内部参数名称前的名称赋予这个参数一个外部名称,这个名称可以和内部参数的名称不同。外部参数名称在函数被调用时必须被使用。对应的参数在方法或函数被调用时必须有外部名。
|
||||
|
||||
@ -393,9 +415,9 @@ f(x: 1, withY: 2, 3) // 参数 x 和 y 是有标签的,参数 z 则没有
|
||||
2. 函数体内部,拷贝后的值被修改。
|
||||
3. 函数返回后,拷贝后的值被赋值给原参数。
|
||||
|
||||
这种行为被称为拷入拷出(copy-in copy-out)或值结果调用(call by value result)。例如,当一个计算型属性或者一个具有属性观察器的属性被用作函数的输入输出参数时,其 getter 会在函数调用时被调用,而其 setter 会在函数返回时被调用。
|
||||
这种行为被称为*拷入拷出 (copy-in copy-out)* 或*值结果调用 (call by value result)*。例如,当一个计算型属性或者一个具有属性观察器的属性被用作函数的输入输出参数时,其 getter 会在函数调用时被调用,而其 setter 会在函数返回时被调用。
|
||||
|
||||
作为一种优化手段,当参数值存储在内存中的物理地址时,在函数体内部和外部均会使用同一内存位置。这种优化行为被称为引用调用(call by reference),它满足了拷入拷出模型的所有需求,而消除了复制带来的开销。不要依赖于拷入拷出与引用调用之间的行为差异。
|
||||
作为一种优化手段,当参数值存储在内存中的物理地址时,在函数体内部和外部均会使用同一内存位置。这种优化行为被称为*引用调用 (call by reference)*,它满足了拷入拷出模型的所有需求,而消除了复制带来的开销。不要依赖于拷入拷出与引用调用之间的行为差异。
|
||||
|
||||
不要使用传递给输入输出参数的值,即使原始值在当前作用域中依然可用。当函数返回时,你对原始值所做的更改会被拷贝的值所覆盖。不要依赖于引用调用的优化机制来试图阻止这种覆盖。
|
||||
|
||||
@ -436,9 +458,11 @@ print(x)
|
||||
|
||||
参数可以被忽略,参数的数量可变,并且还可以提供默认值,使用形式如下:
|
||||
|
||||
> _ : `参数类型`
|
||||
> `参数名称`: `参数类型`...
|
||||
> `参数名称`: `参数类型` = `默认参数值`
|
||||
```swift
|
||||
_ : <#参数类型#>
|
||||
<#参数名称#>: <#参数类型#>...
|
||||
<#参数名称#.: <#参数类型#> = <#默认参数值#>
|
||||
```
|
||||
|
||||
以下划线(`_`)命名的参数是被显式忽略的,无法在函数体内使用。
|
||||
|
||||
@ -462,80 +486,14 @@ f(x: 7) // 无效,该参数没有外部名称
|
||||
|
||||
枚举或者结构体中的类型方法,要以 `static` 声明修饰符标记,而对于类中的类型方法,除了使用 `static`,也可使用 `class` 声明修饰符标记。
|
||||
|
||||
<a name="curried_functions"></a>
|
||||
### 柯里化函数
|
||||
|
||||
可以将一个带有多个参数的函数重写为一个等价的函数,这个重写后的函数只有一个参数并且返回一个函数。这个返回的函数接受下一个参数,并且返回另外一个函数。如此一直持续到再没有剩余的参数,最终返回的函数返回最初的多参函数要返回的原始值。这种重写的函数被称为柯里化函数。例如,可以为 `addTwoInts(a:b:)` 函数重写一个等价的 `addTwoIntsCurried(a:)(b:)` 函数:
|
||||
|
||||
```swift
|
||||
func addTwoInts(a a: Int, b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func addTwoIntsCurried(a a: Int) -> (Int -> Int) {
|
||||
func addTheOtherInt(b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
return addTheOtherInt
|
||||
}
|
||||
```
|
||||
|
||||
`addTwoInts(a:b:)` 函数接受两个整型值并且返回它们的和。`addTwoIntsCurried(a:)(b:)` 函数接受一个整型值,并且返回另外一个接受第二个整型值的函数,该函数会将其参数和第一个整型值相加。(这个嵌套函数会从外层函数中捕获第一个整型值)。
|
||||
|
||||
在 Swift 中,可以通过以下语法非常简明地编写一个柯里化函数:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数)(参数) -> 返回类型 {
|
||||
语句
|
||||
}
|
||||
```
|
||||
|
||||
举例来说,下面的两个声明是等价的:
|
||||
|
||||
```swift
|
||||
func addTwoIntsCurried(a a: Int)(b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func addTwoIntsCurried(a a: Int) -> (Int -> Int) {
|
||||
func addTheOtherInt(b: Int) -> Int {
|
||||
return a + b
|
||||
}
|
||||
return addTheOtherInt
|
||||
}
|
||||
```
|
||||
|
||||
为了像使用非柯里化函数一样的方式使用 `addTwoIntsCurried(a:)(b:)` 函数,必须用第一个整型参数调用 `addTwoIntsCurried(a:)(b:)`,紧接着用第二个整型参数调用其返回的函数:
|
||||
|
||||
```swift
|
||||
addTwoInts(a: 4, b: 5)
|
||||
// 返回值为 9
|
||||
addTwoIntsCurried(a: 4)(b: 5)
|
||||
// 返回值为 9
|
||||
```
|
||||
|
||||
调用一个非柯里化函数时必须一次性提供所有的参数,而使用函数的柯里化形式则可以分多次提供参数,每次调用提供一个(甚至可以在代码中的不同地方)。这被称为偏函数应用。例如,可以为 `addTwoIntsCurried(a:)(b:)` 函数提供整形参数 `1`,然后把返回的函数赋值给常量 `plusOne`:
|
||||
|
||||
```swift
|
||||
let plusOne = addTwoIntsCurried(a: 1)
|
||||
// plusOne 是类型为 Int -> Int 的函数
|
||||
```
|
||||
|
||||
因为 `plusOne` 是函数 `addTwoIntsCurried(a:)(b:)` 的首个参数为 `1` 时返回的函数,所以可以调用 `plusOne` 并传入一个整型值使其和 `1` 相加。
|
||||
|
||||
```swift
|
||||
plusOne(b: 10)
|
||||
// 返回值为 11
|
||||
```
|
||||
|
||||
<a name="throwing_functions_and_methods"></a>
|
||||
### 抛出错误的函数和方法
|
||||
|
||||
可以抛出错误的函数或方法必须使用 `throws` 关键字标记。这类函数和方法被称为抛出函数和抛出方法。它们有着下面的形式:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) throws -> 返回类型 {
|
||||
语句
|
||||
func <#函数名称#>(<#参数列表#>) throws -> <#返回类型#> {
|
||||
<#语句#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -558,6 +516,8 @@ func functionWithCallback(callback: () throws -> Int) rethrows {
|
||||
}
|
||||
```
|
||||
|
||||
重抛函数或者方法不能够从它本身直接抛出任何错误,这意味着它不能够包含 `throw` 语句。它只能够传递作为参数的抛出函数所抛出的错误。例如,在 `do-catch` 代码块中调用抛出函数,以及在 `catch` 闭包中处理另一种抛出的错误错误都是不允许的。
|
||||
|
||||
抛出方法不能重写重抛方法,而且抛出方法不能满足协议对于重抛方法的要求。也就是说,重抛方法可以重写抛出方法,而且重抛方法可以满足协议对于抛出方法的要求。
|
||||
|
||||
<a name="grammer_of_a_function_declaration"></a>
|
||||
@ -568,39 +528,38 @@ func functionWithCallback(callback: () throws -> Int) rethrows {
|
||||
|
||||
<a name="function-head"></a>
|
||||
> *函数头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **func**
|
||||
<a name="function-name"></a>
|
||||
> <a name="function-name"></a>
|
||||
> *函数名* → [*标识符*](02_Lexical_Structure.md#identifier) | [*运算符*](02_Lexical_Structure.md#operator)
|
||||
|
||||
<a name="function-signature"></a>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **throws**<sub>可选</sub> [*函数结果*](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [*参数子句列表*](#parameter-clauses) **rethrows** [*函数结果*](#function-result)<sub>可选</sub>
|
||||
<a name="function-result"></a>
|
||||
> <a name="function-result"></a>
|
||||
> *函数结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
<a name="function-body"></a>
|
||||
> <a name="function-body"></a>
|
||||
> *函数体* → [*代码块*](#code-block)
|
||||
|
||||
<a name="parameter-clauses"></a>
|
||||
> *参数子句列表* → [*参数子句*](#parameter-clause) [*参数子句列表*](#parameter-clauses)<sub>可选</sub>
|
||||
<a name="parameter-clause"></a>
|
||||
> <a name="parameter-clause"></a>
|
||||
> *参数子句* → **(** **)** | **(** [*参数列表*](#parameter-list) **)**
|
||||
<a name="parameter-list"></a>
|
||||
> <a name="parameter-list"></a>
|
||||
> *参数列表* → [*参数*](#parameter) | [*参数*](#parameter) **,** [*参数列表*](#parameter-list)
|
||||
<a name="parameter"></a>
|
||||
> <a name="parameter"></a>
|
||||
> *参数* → **let**<sub>可选</sub> [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) [*默认参数子句*](#default-argument-clause)<sub>可选</sub>
|
||||
> *参数* → **var** [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) [*默认参数子句*](#default-argument-clause)<sub>可选</sub>
|
||||
> *参数* → **inout** [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation)
|
||||
> *参数* → [*外部参数名*](#external-parameter-name)<sub>可选</sub> [*内部参数名*](#local-parameter-name) [*类型标注*](03_Types.md#type-annotation) **...**
|
||||
<a name="external-parameter-name"></a>
|
||||
> <a name="external-parameter-name"></a>
|
||||
> *外部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
<a name="local-parameter-name"></a>
|
||||
> <a name="local-parameter-name"></a>
|
||||
> *内部参数名* → [*标识符*](02_Lexical_Structure.md#identifier) | **_**
|
||||
<a name="default-argument-clause"></a>
|
||||
> <a name="default-argument-clause"></a>
|
||||
> *默认参数子句* → **=** [*表达式*](04_Expressions.md#expression)
|
||||
|
||||
<a name="enumeration_declaration"></a>
|
||||
## 枚举声明
|
||||
|
||||
在程序中使用枚举声明来引入一个枚举类型。
|
||||
在程序中使用*枚举声明 (enumeration declaration)* 来引入一个枚举类型。
|
||||
|
||||
枚举声明有两种基本形式,使用关键字 `enum` 来声明。枚举声明体包含零个或多个值,称为枚举用例,还可包含任意数量的声明,包括计算型属性,实例方法,类型方法,构造器,类型别名,甚至其他枚举,结构体,和类。枚举声明不能包含析构器或者协议声明。
|
||||
|
||||
@ -618,9 +577,9 @@ func functionWithCallback(callback: () throws -> Int) rethrows {
|
||||
如下的形式声明了一个包含任意类型枚举用例的枚举变量:
|
||||
|
||||
```swift
|
||||
enum 枚举名称: 采纳的协议 {
|
||||
case 枚举用例1
|
||||
case 枚举用例2(关联值类型)
|
||||
enum <#枚举名称#>: <#采纳的协议#> {
|
||||
case <#枚举用例1#>
|
||||
case <#枚举用例2#>(<#关联值类型#>)
|
||||
}
|
||||
```
|
||||
|
||||
@ -669,9 +628,9 @@ enum Tree<T> {
|
||||
以下形式声明了一种枚举类型,其中各个枚举用例的类型均为同一种基本类型:
|
||||
|
||||
```swift
|
||||
enum 枚举名称: 原始值类型, 采纳的协议 {
|
||||
case 枚举用例1 = 原始值1
|
||||
case 枚举用例2 = 原始值2
|
||||
enum <#枚举名称#>: <#原始值类型#>, <#采纳的协议#> {
|
||||
case <#枚举用例1#> = <#原始值1#>
|
||||
case <#枚举用例2#> = <#原始值2#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -715,46 +674,46 @@ enum WeekendDay: String {
|
||||
|
||||
<a name="union-style-enum"></a>
|
||||
> *联合风格枚举* → **indirect**<sub>可选</sub> **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> **{** [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub> **}**
|
||||
<a name="union-style-enum-members"></a>
|
||||
> <a name="union-style-enum-members"></a>
|
||||
> *多个联合风格枚举成员* → [*联合风格枚举成员*](#union-style-enum-member) [*多个联合风格枚举成员*](#union-style-enum-members)<sub>可选</sub>
|
||||
<a name="union-style-enum-member"></a>
|
||||
> <a name="union-style-enum-member"></a>
|
||||
> *联合风格枚举成员* → [*声明*](#declaration) | [*联合风格枚举用例子句*](#union-style-enum-case-clause)
|
||||
<a name="union-style-enum-case-clause"></a>
|
||||
> <a name="union-style-enum-case-clause"></a>
|
||||
> *联合风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **indirect**<sub>可选</sub> **case** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
<a name="union-style-enum-case-list"></a>
|
||||
> <a name="union-style-enum-case-list"></a>
|
||||
> *联合风格枚举用例列表* → [*联合风格枚举用例*](#union-style-enum-case) | [*联合风格枚举用例*](#union-style-enum-case) **,** [*联合风格枚举用例列表*](#union-style-enum-case-list)
|
||||
<a name="union-style-enum-case"></a>
|
||||
> <a name="union-style-enum-case"></a>
|
||||
> *联合风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*元组类型*](03_Types.md#tuple-type)<sub>可选</sub>
|
||||
<a name="enum-name"></a>
|
||||
> <a name="enum-name"></a>
|
||||
> *枚举名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="enum-case-name"></a>
|
||||
> <a name="enum-case-name"></a>
|
||||
> *枚举用例名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
|
||||
<a name="raw-value-style-enum"></a>
|
||||
> *原始值风格枚举* → **enum** [*枚举名称*](#enum-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause) **{** [*多个原始值风格枚举成员*](#raw-value-style-enum-members) **}**
|
||||
<a name="raw-value-style-enum-members"></a>
|
||||
> <a name="raw-value-style-enum-members"></a>
|
||||
> *多个原始值风格枚举成员* → [*原始值风格枚举成员*](#raw-value-style-enum-member) [*多个原始值风格枚举成员*](#raw-value-style-enum-members)<sub>可选</sub>
|
||||
<a name="raw-value-style-enum-member"></a>
|
||||
> <a name="raw-value-style-enum-member"></a>
|
||||
> *原始值风格枚举成员* → [*声明*](#declaration) | [*原始值风格枚举用例子句*](#raw-value-style-enum-case-clause)
|
||||
<a name="raw-value-style-enum-case-clause"></a>
|
||||
> <a name="raw-value-style-enum-case-clause"></a>
|
||||
> *原始值风格枚举用例子句* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **case** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
<a name="raw-value-style-enum-case-list"></a>
|
||||
> <a name="raw-value-style-enum-case-list"></a>
|
||||
> *原始值风格枚举用例列表* → [*原始值风格枚举用例*](#raw-value-style-enum-case) | [*原始值风格枚举用例*](#raw-value-style-enum-case) **,** [*原始值风格枚举用例列表*](#raw-value-style-enum-case-list)
|
||||
<a name="raw-value-style-enum-case"></a>
|
||||
> <a name="raw-value-style-enum-case"></a>
|
||||
> *原始值风格枚举用例* → [*枚举用例名称*](#enum-case-name) [*原始值赋值*](#raw-value-assignment)<sub>可选</sub>
|
||||
<a name="raw-value-assignment"></a>
|
||||
> <a name="raw-value-assignment"></a>
|
||||
> *原始值赋值* → **=** [*原始值字面量*](#raw-value-literal)
|
||||
<a name="raw-value-literal"></a>
|
||||
> <a name="raw-value-literal"></a>
|
||||
> *原始值字面量* → [数字型字面量](02_Lexical_Structure.md#numeric-literal) | [字符串型字面量](02_Lexical_Structure.md#static-string-literal) | [布尔型字面量](02_Lexical_Structure.md#boolean-literal)
|
||||
|
||||
<a name="structure_declaration"></a>
|
||||
## 结构体声明
|
||||
|
||||
使用结构体声明可以在程序中引入一个结构体类型。结构体声明使用 `struct` 关键字,遵循如下的形式:
|
||||
使用*结构体声明 (structure declaration)* 可以在程序中引入一个结构体类型。结构体声明使用 `struct` 关键字,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
struct 结构体名称: 采纳的协议 {
|
||||
多条声明
|
||||
struct <#结构体名称#>: <#采纳的协议#> {
|
||||
<#多条声明#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -781,21 +740,21 @@ struct 结构体名称: 采纳的协议 {
|
||||
|
||||
<a name="grammer_of_a_structure_declaration"></a>
|
||||
> 结构体声明语法
|
||||
<a name="struct-declaration"></a>
|
||||
> <a name="struct-declaration"></a>
|
||||
> *结构体声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*访问级别修饰符*](#access-level-modifier) <sub>可选</sub> **struct** [*结构体名称*](#struct-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [类型继承子句](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*结构体主体*](#struct-body)
|
||||
<a name="struct-name"></a>
|
||||
> <a name="struct-name"></a>
|
||||
> *结构体名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="struct-body"></a>
|
||||
> <a name="struct-body"></a>
|
||||
> *结构体主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="class_declaration"></a>
|
||||
## 类声明
|
||||
|
||||
可以在程序中使用类声明来引入一个类。类声明使用关键字 `class`,遵循如下的形式:
|
||||
可以在程序中使用*类声明 (class declaration)* 来引入一个类。类声明使用关键字 `class`,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
class 类名: 超类, 采纳的协议 {
|
||||
多条声明
|
||||
class <#类名#>: <#超类#>, <#采纳的协议#> {
|
||||
<#多条声明#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -825,21 +784,21 @@ class 类名: 超类, 采纳的协议 {
|
||||
|
||||
<a name="grammer_of_a_class_declaration"></a>
|
||||
> 类声明语法
|
||||
<a name="class-declaration"></a>
|
||||
> <a name="class-declaration"></a>
|
||||
> *类声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **class** [*类名*](#class-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类主体*](#class-body)
|
||||
<a name="class-name"></a>
|
||||
> <a name="class-name"></a>
|
||||
> *类名* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="class-body"></a>
|
||||
> <a name="class-body"></a>
|
||||
> *类主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="protocol_declaration"></a>
|
||||
## 协议声明
|
||||
|
||||
协议声明可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
||||
*协议声明 (protocol declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
||||
|
||||
```swift
|
||||
protocol 协议名称: 继承的协议 {
|
||||
协议成员声明
|
||||
protocol <#协议名称#>: <#继承的协议#> {
|
||||
<#协议成员声明#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -876,9 +835,9 @@ protocol SomeProtocol: class {
|
||||
|
||||
<a name="protocol-declaration"></a>
|
||||
> *协议声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **protocol** [*协议名称*](#protocol-name) [*类型继承子句*](03_Types.html#type-inheritance-clause)<sub>可选</sub> [*协议主体*](#protocol-body)
|
||||
<a name="protocol-name"></a>
|
||||
> <a name="protocol-name"></a>
|
||||
> *协议名称* → [*标识符*](02_Lexical_Structure.md#identifier)
|
||||
<a name="protocol-body"></a>
|
||||
> <a name="protocol-body"></a>
|
||||
> *协议主体* → **{** [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="protocol-member-declaration"></a>
|
||||
@ -887,7 +846,7 @@ protocol SomeProtocol: class {
|
||||
> *协议成员声明* → [*协议构造器声明*](#protocol-initializer-declaration)
|
||||
> *协议成员声明* → [*协议下标声明*](#protocol-subscript-declaration)
|
||||
> *协议成员声明* → [*协议关联类型声明*](#protocol-associated-type-declaration)
|
||||
<a name="protocol-member-declarations"></a>
|
||||
> <a name="protocol-member-declarations"></a>
|
||||
> *协议成员声明列表* → [*协议成员声明*](#protocol-member-declaration) [*协议成员声明列表*](#protocol-member-declarations)<sub>可选</sub>
|
||||
|
||||
<a name="protocol_property_declaration"></a>
|
||||
@ -895,7 +854,9 @@ protocol SomeProtocol: class {
|
||||
|
||||
协议可以通过在协议声明主体中引入一个协议属性声明,来声明符合的类型必须实现的属性。协议属性声明有一种特殊的变量声明形式:
|
||||
|
||||
> var `属性名`: `类型` { get set }
|
||||
```swift
|
||||
var <#属性名#>: <#类型#> { get set }
|
||||
```
|
||||
|
||||
同其它协议成员声明一样,这些属性声明仅仅针对符合该协议的类型声明了 getter 和 setter 要求,你不能在协议中直接实现 getter 和 setter。
|
||||
|
||||
@ -905,7 +866,7 @@ protocol SomeProtocol: class {
|
||||
|
||||
<a name="grammer_of_an_import_declaration"></a>
|
||||
> 协议属性声明语法
|
||||
<a name="protocol-property-declaration"></a>
|
||||
> <a name="protocol-property-declaration"></a>
|
||||
> *协议属性声明* → [*变量声明头*](#variable-declaration-head) [*变量名称*](#variable-name) [*类型标注*](03_Types.md#type-annotation) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
|
||||
<a name="protocol_method_declaration"></a>
|
||||
@ -919,7 +880,7 @@ protocol SomeProtocol: class {
|
||||
|
||||
<a name="grammer_of_a_protocol_declaration"></a>
|
||||
> 协议方法声明语法
|
||||
<a name="protocol-method-declaration"></a>
|
||||
> <a name="protocol-method-declaration"></a>
|
||||
> *协议方法声明* → [*函数头*](#function-head) [*函数名*](#function-name) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*函数签名*](#function-signature)
|
||||
|
||||
<a name="protocol_initializer_declaration"></a>
|
||||
@ -936,7 +897,7 @@ protocol SomeProtocol: class {
|
||||
|
||||
<a name="grammer_of_a_protocol_initializer_declaration"></a>
|
||||
> 协议构造器声明语法
|
||||
<a name="protocol-initializer-declaration"></a>
|
||||
> <a name="protocol-initializer-declaration"></a>
|
||||
> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub>
|
||||
> *协议构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **rethrows**
|
||||
|
||||
@ -945,7 +906,9 @@ protocol SomeProtocol: class {
|
||||
|
||||
协议可以通过在协议声明主体中引入一个协议下标声明,来声明符合的类型必须实现的下标。协议下标声明有一个特殊的下标声明形式:
|
||||
|
||||
> subscript (`参数列表`) -> `返回类型` { get set }
|
||||
```swift
|
||||
subscript (<#参数列表#>) -> <#返回类型#> { get set }
|
||||
```
|
||||
|
||||
下标声明只为符合类型声明了 getter 和 setter 要求。如果下标声明包含 `get` 和 `set` 关键字,符合类型也必须实现 getter 和 setter 子句。如果下标声明只包含 `get` 关键字,符合类型必须实现 getter 子句,可以选择是否实现 setter 子句。
|
||||
|
||||
@ -953,19 +916,19 @@ protocol SomeProtocol: class {
|
||||
|
||||
<a name="grammer_of_a_protocol_subscript_declaration"></a>
|
||||
> 协议下标声明语法
|
||||
<a name="protocol-subscript-declaration"></a>
|
||||
> <a name="protocol-subscript-declaration"></a>
|
||||
> *协议下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
|
||||
<a name="protocol_associated_type_declaration"></a>
|
||||
### 协议关联类型声明
|
||||
|
||||
使用关键字 `typealias` 来声明协议关联类型。关联类型为作为协议声明的一部分,为某种类型提供了一个别名。关联类型和泛型参数子句中的类型参数很相似,但是它们和 `Self` 一样,用于协议中。`Self` 指代采纳协议的类型。要获得更多信息和例子,请参阅 [关联类型](../chapter2/23_Generics.md#associated_types)。
|
||||
使用关键字 `associatedtype` 来声明协议关联类型。关联类型为作为协议声明的一部分,为某种类型提供了一个别名。关联类型和泛型参数子句中的类型参数很相似,但是它们和 `Self` 一样,用于协议中。`Self` 指代采纳协议的类型。要获得更多信息和例子,请参阅 [关联类型](../chapter2/23_Generics.md#associated_types)。
|
||||
|
||||
另请参阅 [类型别名声明](#type_alias_declaration)。
|
||||
|
||||
<a name="grammer_of_a_protocol_associated_type_declaration"></a>
|
||||
> 协议关联类型声明语法
|
||||
<a name="protocol-associated-type-declaration"></a>
|
||||
> <a name="protocol-associated-type-declaration"></a>
|
||||
> *协议关联类型声明* → [*类型别名头*](#typealias-head) [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*类型别名赋值*](#typealias-assignment)<sub>可选</sub>
|
||||
|
||||
<a name="initializer_declaration"></a>
|
||||
@ -978,8 +941,8 @@ protocol SomeProtocol: class {
|
||||
采用如下形式声明结构体和枚举的构造器,以及类的指定构造器:
|
||||
|
||||
```swift
|
||||
init(参数列表) {
|
||||
构造语句
|
||||
init(<#参数列表#>) {
|
||||
<#构造语句#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -992,8 +955,8 @@ init(参数列表) {
|
||||
要为类声明一个便利构造器,用 `convenience` 声明修饰符来标记构造器声明:
|
||||
|
||||
```swift
|
||||
convenience init(参数列表) {
|
||||
构造语句
|
||||
convenience init(<#参数列表#>) {
|
||||
<#构造语句#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -1043,7 +1006,7 @@ if let actualInstance = SomeStruct(input: "Hello") {
|
||||
}
|
||||
```
|
||||
|
||||
结构体或者枚举的可失败构造器可以在构造器实现中的任意位置返回 `nil`。然而,对于类的可失败构造器,仅在类的所有存储属性被初始化之后,并且 `self.init` 或 `super.init` 被调用之后(就是说,构造器委托过程完成后)才能返回 `nil`。
|
||||
结构体或者枚举的可失败构造器可以在构造器实现中的任意位置返回 `nil`。
|
||||
|
||||
可失败构造器可以委托任意种类的构造器。非可失败可以委托其它非可失败构造器或者 `init!` 可失败构造器。非可失败构造器可以委托超类的 `init?` 可失败指定构造器,但是需要使用强制解包,例如 `super.init()!`。
|
||||
|
||||
@ -1055,24 +1018,24 @@ if let actualInstance = SomeStruct(input: "Hello") {
|
||||
|
||||
<a name="grammer_of_an_initializer_declaration"></a>
|
||||
> 构造器声明语法
|
||||
<a name="initializer-declaration"></a>
|
||||
> <a name="initializer-declaration"></a>
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **throws**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
> *构造器声明* → [*构造器头*](#initializer-head) [*泛型形参子句*](08_Generic_Parameters_and_Arguments.md#generic-parameter-clause)<sub>可选</sub> [*参数子句*](#parameter-clause) **rethrows**<sub>可选</sub> [*构造器主体*](#initializer-body)
|
||||
<a name="initializer-head"></a>
|
||||
> <a name="initializer-head"></a>
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **?**
|
||||
> *构造器头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **init** **!**
|
||||
<a name="initializer-body"></a>
|
||||
> <a name="initializer-body"></a>
|
||||
> *构造器主体* → [*代码块*](#code-block)
|
||||
|
||||
<a name="deinitializer_declaration"></a>
|
||||
## 析构器声明
|
||||
|
||||
析构器声明可以为类声明一个析构器。析构器没有参数,遵循如下格式:
|
||||
*析构器声明 (deinitializer declaration)* 可以为类声明一个析构器。析构器没有参数,遵循如下格式:
|
||||
|
||||
```swift
|
||||
deinit {
|
||||
语句
|
||||
<#语句#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -1086,17 +1049,17 @@ deinit {
|
||||
|
||||
<a name="grammer_of_a_deinitializer_declaration"></a>
|
||||
> 析构器声明语法
|
||||
<a name="deinitializer-declaration"></a>
|
||||
> <a name="deinitializer-declaration"></a>
|
||||
> *析构器声明* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> **deinit** [*代码块*](#code-block)
|
||||
|
||||
<a name="extension_declaration"></a>
|
||||
## 扩展声明
|
||||
|
||||
扩展声明可以扩展一个现存的类,结构体,和枚举类型的行为。扩展声明使用关键字 `extension`,遵循如下格式:
|
||||
*扩展声明 (extension declaration)* 可以扩展一个现存的类,结构体,和枚举类型的行为。扩展声明使用关键字 `extension`,遵循如下格式:
|
||||
|
||||
```swift
|
||||
extension 类型名称: 采纳的协议 {
|
||||
声明语句
|
||||
extension <#类型名称#>: <#采纳的协议#> {
|
||||
<#声明语句#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -1110,23 +1073,23 @@ extension 类型名称: 采纳的协议 {
|
||||
|
||||
<a name="grammer_of_an_extension_declaration"></a>
|
||||
> 扩展声明语法
|
||||
<a name="extension-declaration"></a>
|
||||
> <a name="extension-declaration"></a>
|
||||
> *扩展声明* → [访问级别修饰符](#access-level-modifier)<sub>可选</sub> **extension** [*类型标识符*](03_Types.md#type-identifier) [*类型继承子句*](03_Types.md#type-inheritance-clause)<sub>可选</sub> [*扩展主体*](#extension-body)
|
||||
<a name="extension-body"></a>
|
||||
> <a name="extension-body"></a>
|
||||
> *扩展主体* → **{** [*多条声明*](#declarations)<sub>可选</sub> **}**
|
||||
|
||||
<a name="subscript_declaration"></a>
|
||||
## 下标声明
|
||||
|
||||
下标声明用于为特定类型的对象添加下标支持,通常也用于为访问集合,列表和序列中的元素提供语法便利。下标声明使用关键字 `subscript`,形式如下:
|
||||
*下标声明 (subscript declaration)* 用于为特定类型的对象添加下标支持,通常也用于为访问集合,列表和序列中的元素提供语法便利。下标声明使用关键字 `subscript`,形式如下:
|
||||
|
||||
```swift
|
||||
subscript (参数列表) -> 返回类型 {
|
||||
subscript (<#参数列表#>) -> <#返回类型#> {
|
||||
get {
|
||||
语句
|
||||
<#语句#>
|
||||
}
|
||||
set(setter 名称) {
|
||||
语句
|
||||
set(<#setter 名称#>) {
|
||||
<#语句#>
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -1147,19 +1110,19 @@ subscript (参数列表) -> 返回类型 {
|
||||
|
||||
<a name="grammer_of_a_subscript_declaration"></a>
|
||||
> 下标声明语法
|
||||
<a name="subscript-declaration"></a>
|
||||
> <a name="subscript-declaration"></a>
|
||||
> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*代码块*](#code-block)
|
||||
> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter代码块*](#getter-setter-block)
|
||||
> *下标声明* → [*下标头*](#subscript-head) [*下标结果*](#subscript-result) [*getter-setter关键字代码块*](#getter-setter-keyword-block)
|
||||
<a name="subscript-head"></a>
|
||||
> <a name="subscript-head"></a>
|
||||
> *下标头* → [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub> **subscript** [*参数子句*](#parameter-clause)
|
||||
<a name="subscript-result"></a>
|
||||
> <a name="subscript-result"></a>
|
||||
> *下标结果* → **->** [*特性列表*](06_Attributes.md#attributes)<sub>可选</sub> [*类型*](03_Types.md#type)
|
||||
|
||||
<a name="operator_declaration"></a>
|
||||
## 运算符声明
|
||||
|
||||
运算符声明会向程序中引入中缀、前缀或后缀运算符,使用关键字 `operator` 来声明。
|
||||
*运算符声明 (operator declaration)* 会向程序中引入中缀、前缀或后缀运算符,使用关键字 `operator` 来声明。
|
||||
|
||||
可以声明三种不同的缀性:中缀、前缀和后缀。运算符的缀性指定了运算符与其运算对象的相对位置。
|
||||
|
||||
@ -1168,9 +1131,9 @@ subscript (参数列表) -> 返回类型 {
|
||||
下面的形式声明了一个新的中缀运算符:
|
||||
|
||||
```swift
|
||||
infix operator 运算符名称 {
|
||||
precedence 优先级
|
||||
associativity 结合性
|
||||
infix operator <#运算符名称#> {
|
||||
precedence <#优先级#>
|
||||
associativity <#结合性#>
|
||||
}
|
||||
```
|
||||
|
||||
@ -1187,20 +1150,20 @@ infix operator 运算符名称 {
|
||||
下面的形式声明了一个新的前缀运算符:
|
||||
|
||||
```swift
|
||||
prefix operator 运算符名称 {}
|
||||
prefix operator <#运算符名称#> {}
|
||||
```
|
||||
|
||||
出现在运算对象前边的前缀运算符是一元运算符,例如表达式 `++i` 中的前缀递增运算符(`++`)。
|
||||
出现在运算对象前边的前缀运算符是一元运算符,例如表达式 `!a` 中的前缀非运算符(`!`)。
|
||||
|
||||
前缀运算符的声明中不指定优先级,而且前缀运算符是非结合的。
|
||||
|
||||
下面的形式声明了一个新的后缀运算符:
|
||||
|
||||
```swift
|
||||
postfix operator 运算符名称 {}
|
||||
postfix operator <#运算符名称#> {}
|
||||
```
|
||||
|
||||
紧跟在运算对象后边的后缀运算符是一元运算符,例如表达式 `i++` 中的后缀递增运算符(`++`)。
|
||||
紧跟在运算对象后边的后缀运算符是一元运算符,例如表达式 `i!` 中的后缀强制解包运算符(`!`)。
|
||||
|
||||
和前缀运算符一样,后缀运算符的声明中不指定优先级,而且后缀运算符是非结合的。
|
||||
|
||||
@ -1214,20 +1177,20 @@ postfix operator 运算符名称 {}
|
||||
|
||||
<a name="prefix-operator-declaration"></a>
|
||||
> *前缀运算符声明* → **prefix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
<a name="postfix-operator-declaration"></a>
|
||||
> <a name="postfix-operator-declaration"></a>
|
||||
> *后缀运算符声明* → **postfix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** **}**
|
||||
<a name="infix-operator-declaration"></a>
|
||||
> <a name="infix-operator-declaration"></a>
|
||||
> *中缀运算符声明* → **infix** **运算符** [*运算符*](02_Lexical_Structure.md#operator) **{** [*中缀运算符属性*](#infix-operator-attributes)<sub>可选</sub> **}**
|
||||
|
||||
<a name="infix-operator-attributes"></a>
|
||||
> *中缀运算符属性* → [*优先级子句*](#precedence-clause)<sub>可选</sub> [*结和性子句*](#associativity-clause)<sub>可选</sub>
|
||||
<a name="precedence-clause"></a>
|
||||
> <a name="precedence-clause"></a>
|
||||
> *优先级子句* → **precedence** [*优先级水平*](#precedence-level)
|
||||
<a name="precedence-level"></a>
|
||||
> <a name="precedence-level"></a>
|
||||
> *优先级水平* → 十进制整数 0 到 255,包含 0 和 255
|
||||
<a name="associativity-clause"></a>
|
||||
> <a name="associativity-clause"></a>
|
||||
> *结和性子句* → **associativity** [*结和性*](#associativity)
|
||||
<a name="associativity"></a>
|
||||
> <a name="associativity"></a>
|
||||
> *结和性* → **left** | **right** | **none**
|
||||
|
||||
<a name="declaration_modifiers"></a>
|
||||
@ -1288,7 +1251,7 @@ Swift 提供了三个级别的访问控制:`public`,`internal` 和 `private`
|
||||
<a name="declaration-modifier"></a>
|
||||
> *声明修饰符* → **class** | **convenience**| **dynamic** | **final** | **infix** | **lazy** | **mutating** | **nonmutating** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
|
||||
> 声明修饰符 → [*访问级别修饰符*](#access-level-modifier)
|
||||
<a name="declaration-modifiers"></a>
|
||||
> <a name="declaration-modifiers"></a>
|
||||
> *声明修饰符列表* → [*声明修饰符*](#declaration-modifier) [*声明修饰符列表*](#declaration-modifiers)<sub>可选</sub>
|
||||
|
||||
<a name="access-level-modifier"></a>
|
||||
|
||||
Reference in New Issue
Block a user