Compare commits
15 Commits
Ch-Types
...
Ch-Declara
| Author | SHA1 | Date | |
|---|---|---|---|
| c70d3aa08f | |||
| 5c54284a30 | |||
| ec01e5ad58 | |||
| afc5008c29 | |||
| c7644e869a | |||
| 3d7dfe15d7 | |||
| 2d05380f78 | |||
| 54c13df117 | |||
| 10f7e8f9a2 | |||
| ff3824c368 | |||
| c59ffce41e | |||
| 80c2ac750d | |||
| 704d910495 | |||
| 0ab60a97c3 | |||
| f43cb3fdb9 |
Binary file not shown.
BIN
document/TheSwiftProgrammingLanguageSwift55.epub
Normal file
BIN
document/TheSwiftProgrammingLanguageSwift55.epub
Normal file
Binary file not shown.
@ -135,7 +135,7 @@ swapTwoValues(&someString, &anotherString)
|
||||
|
||||
```swift
|
||||
struct IntStack {
|
||||
var items = [Int]()
|
||||
var items: [Int] = []
|
||||
mutating func push(_ item: Int) {
|
||||
items.append(item)
|
||||
}
|
||||
@ -153,7 +153,7 @@ struct IntStack {
|
||||
|
||||
```swift
|
||||
struct Stack<Element> {
|
||||
var items = [Element]()
|
||||
var items: [Element] = []
|
||||
mutating func push(_ item: Element) {
|
||||
items.append(item)
|
||||
}
|
||||
@ -354,7 +354,7 @@ protocol Container {
|
||||
```swift
|
||||
struct IntStack: Container {
|
||||
// IntStack 的原始实现部分
|
||||
var items = [Int]()
|
||||
var items: [Int] = []
|
||||
mutating func push(_ item: Int) {
|
||||
items.append(item)
|
||||
}
|
||||
@ -386,7 +386,7 @@ struct IntStack: Container {
|
||||
```swift
|
||||
struct Stack<Element>: Container {
|
||||
// Stack<Element> 的原始实现部分
|
||||
var items = [Element]()
|
||||
var items: [Element] = []
|
||||
mutating func push(_ item: Element) {
|
||||
items.append(item)
|
||||
}
|
||||
@ -721,7 +721,7 @@ protocol ComparableContainer: Container where Item: Comparable { }
|
||||
extension Container {
|
||||
subscript<Indices: Sequence>(indices: Indices) -> [Item]
|
||||
where Indices.Iterator.Element == Int {
|
||||
var result = [Item]()
|
||||
var result: [Item] = []
|
||||
for index in indices {
|
||||
result.append(self[index])
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ Swift 的*“词法结构(lexical structure)”* 描述了能构成该语言
|
||||
|
||||
## 空白与注释 {#whitespace}
|
||||
|
||||
空白(whitespace)有两个用途:分隔源文件中的符号以及帮助区分运算符属于前缀还是后缀(参见 [运算符](#operators)),在其他情况下空白则会被忽略。以下的字符会被当作空白:空格(U+0020)、换行符(U+000A)、回车符(U+000D)、水平制表符(U+0009)、垂直制表符(U+000B)、换页符(U+000C)以及空字符(U+0000)。
|
||||
空白(whitespace)有两个用途:分隔源文件中的符号和区分前缀、后缀和二元运算符(参见 [运算符](#operators)),在其他情况下空白则会被忽略。以下的字符会被当作空白:空格(U+0020)、换行符(U+000A)、回车符(U+000D)、水平制表符(U+0009)、垂直制表符(U+000B)、换页符(U+000C)以及空字符(U+0000)。
|
||||
|
||||
注释被编译器当作空白处理。单行注释由 `//` 开始直至遇到换行符(U+000A)或者回车符(U+000D)。多行注释由 `/*` 开始,以 `*/` 结束。多行注释允许嵌套,但注释标记必须成对出现。
|
||||
|
||||
|
||||
@ -129,7 +129,7 @@ someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
||||
|
||||
你可以对形参类型为 `() -> T`(其中 T 是任何类型)的函数使用 `autoclosure` 特性,这会在调用侧隐式创建一个闭包。这从语法结构上提供了一种便捷:延迟对表达式的求值,直到其值在函数体中被调用。以自动闭包做为形参的函数类型的例子详见 [自动闭包](../02_language_guide/07_Closures.md#autoclosures)。
|
||||
|
||||
函数类型可以拥有一个可变参数在*形参类型*中。从语法角度上讲,可变参数由一个基础类型名字紧随三个点(`...`)组成,如 `Int...`。可变参数被认为是一个包含了基础类型元素的数组。即 `Int...` 就是 `[Int]`。关于使用可变参数的例子,请参阅 [可变参数](../02_language_guide/06_Functions.md#variadic-parameters)。
|
||||
函数类型可以拥有多个可变参数在*形参类型*中。从语法角度上讲,可变参数由一个基础类型名字紧随三个点(`...`)组成,如 `Int...`。可变参数被认为是一个包含了基础类型元素的数组。即 `Int...` 就是 `[Int]`。关于使用可变参数的例子,请参阅 [可变参数](../02_language_guide/06_Functions.md#variadic-parameters)。
|
||||
|
||||
为了指定一个 `in-out` 参数,可以在形参类型前加 `inout` 前缀。但是你不可以对可变参数或返回值类型使用 `inout`。关于这种形参的详细讲解请参阅 [输入输出参数](../02_language_guide/06_Functions.md#in-out-parameters)。
|
||||
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
>
|
||||
> *声明* → [类声明](#class-declaration)
|
||||
>
|
||||
> *声明* → [actor 声明](#actor-declaration)
|
||||
>
|
||||
> *声明* → [协议声明](#protocol-declaration)
|
||||
>
|
||||
> *声明* → [构造器声明](#initializer-declaration)
|
||||
@ -481,7 +483,7 @@ repeatGreeting("Hello, world!", count: 2) // count 有标签, greeting 没有
|
||||
|
||||
更多关于内存安全和内存独占权的讨论,请参阅 [内存安全](../02_language_guide/24_Memory_Safety.md)。
|
||||
|
||||
如果一个闭包或者嵌套函数捕获了一个输入输出参数,那么这个闭包或者嵌套函数必须是非逃逸的。如果你需要捕获一个输入输出参数,但并不对其进行修改或者在其他代码中观察其值变化,那么你可以使用捕获列表来显式地表明这是个不可变捕获。
|
||||
如果一个闭包或者嵌套函数捕获了一个输入输出参数,那么这个闭包或者嵌套函数必须是非逃逸的。如果你需要捕获一个输入输出参数,但并不对其进行修改,那么你可以使用捕获列表来显式地表明这是个不可变捕获。
|
||||
|
||||
```swift
|
||||
func someFunction(a: inout Int) -> () -> Int {
|
||||
@ -518,7 +520,7 @@ _ : 参数类型
|
||||
|
||||
以下划线(`_`)命名的参数会被显式忽略,无法在函数内使用。
|
||||
|
||||
一个参数的基本类型名称如果紧跟着三个点(`...`),会被视为可变参数。一个函数至多可以拥有一个可变参数,且必须是最后一个参数。可变参数会作为包含该参数类型元素的数组处理。举例来讲,可变参数 `Int...` 会作为 `[Int]` 来处理。关于使用可变参数的例子,请参阅 [可变参数](../02_language_guide/06_Functions.md#variadic-parameters)。
|
||||
一个参数的基本类型名称如果紧跟着三个点(`...`),会被视为可变参数。紧随在可变参数后的参数必须拥有参数标签。一个函数可以拥有多个可变参数。可变参数会作为包含该参数类型元素的数组处理。举例来讲,可变参数 `Int...` 会作为 `[Int]` 来处理。关于使用可变参数的例子,请参阅 [可变参数](../02_language_guide/06_Functions.md#variadic-parameters)。
|
||||
|
||||
如果在参数类型后面有一个以等号(`=`)连接的表达式,该参数会拥有默认值,即给定表达式的值。当函数被调用时,给定的表达式会被求值。如果参数在函数调用时被省略了,就会使用其默认值。
|
||||
|
||||
@ -568,10 +570,10 @@ let someFunction1: (Int, Int) -> Void = callable(_:scale:) // Error
|
||||
let someFunction2: (Int, Int) -> Void = callable.callAsFunction(_:scale:)
|
||||
```
|
||||
|
||||
如 [dynamicmemberlookup](./07_Attributes.md#dynamicmemberlookup) 描述的一样,`subscript(dynamicMemberLookup:)` 下标允许成员查找的语法糖。
|
||||
如 [dynamicmemberlookup](./07_Attributes.md#dynamicmemberlookup) 描述的一样,`subscript(dynamicMember:)` 下标允许成员查找的语法糖。
|
||||
|
||||
### 抛出错误的函数和方法 {#throwing-functions-and-methods}
|
||||
可以抛出错误的函数或方法必须使用 `throws` 关键字标记。这类函数和方法被称为抛出函数和抛出方法。它们有着下面的形式:
|
||||
可以抛出错误的函数或方法必须使用 `throws` 关键字标记。这类函数和方法被称为抛出函数和抛出方法。它们有着下面的形式:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) throws -> 返回类型 {
|
||||
@ -612,7 +614,21 @@ func someFunction(callback: () throws -> Void) rethrows {
|
||||
}
|
||||
```
|
||||
|
||||
抛出方法不能重写重抛方法,而且抛出方法不能满足协议对于重抛方法的要求。也就是说,重抛方法可以重写抛出方法,而且重抛方法可以满足协议对于抛出方法的要求。
|
||||
抛出方法不能重写重抛方法,而且抛出方法不能满足协议对于重抛方法的要求。也就是说,重抛方法可以重写抛出方法,而且重抛方法可以满足对抛出方法的协议要求。
|
||||
|
||||
|
||||
### 异步函数和方法 {#asynchronous-functions-and-methods}
|
||||
异步运行的函数和方法必须用 `async` 关键字标记。这些函数和方法称为异步函数和异步方法。它们有着下面的形式:
|
||||
|
||||
```swift
|
||||
func 函数名称(参数列表) async -> 返回类型 {
|
||||
语句
|
||||
}
|
||||
```
|
||||
|
||||
对异步函数或异步方法的调用必须包含在 `await` 表达式中,即它们必须在 `await` 操作符的作用域内。
|
||||
|
||||
`async` 关键字是函数类型中的一部分。同步函数是异步函数的子类型。所以,你可以在使用异步函数的地方,使用同步函数。同步方法可以重写异步方法,且同步方法可以满足对异步方法的协议要求。
|
||||
|
||||
### 永不返回的函数 {#functions-that-never-return}
|
||||
Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它的调用者。`Never` 返回类型的函数或方法可以称为不归,不归函数、方法要么引发不可恢复的错误,要么永远不停地运作,这会使调用后本应执行得代码就不再执行了。但即使是不归函数、方法,抛错函数和重抛出函数也可以将程序控制转移到合适的 `catch` 代码块。
|
||||
@ -644,9 +660,9 @@ Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它
|
||||
#### function-signature {#function-signature}
|
||||
>
|
||||
>
|
||||
> *函数签名* → [参数子句列表](#parameter-clauses) **throws**<sub>可选</sub> [函数结果](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [参数子句列表](#parameter-clauses) **async**<sub>可选</sub> **throws**<sub>可选</sub> [函数结果](#function-result)<sub>可选</sub>
|
||||
>
|
||||
> *函数签名* → [参数子句列表](#parameter-clauses) **rethrows** [函数结果](#function-result)<sub>可选</sub>
|
||||
> *函数签名* → [参数子句列表](#parameter-clauses) **async**<sub>可选</sub> **rethrows** [函数结果](#function-result)<sub>可选</sub>
|
||||
>
|
||||
>
|
||||
#### function-result {#function-result}
|
||||
@ -697,7 +713,7 @@ Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它
|
||||
## 枚举声明 {#enumeration-declaration}
|
||||
在程序中使用*枚举声明(enumeration declaration)* 来引入一个枚举类型。
|
||||
|
||||
枚举声明有两种基本形式,使用关键字 `enum` 来声明。枚举声明体包含零个或多个值,称为枚举用例,还可包含任意数量的声明,包括计算型属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体和类。枚举声明不能包含析构器或者协议声明。
|
||||
枚举声明有两种基本形式,使用关键字 `enum` 来声明。枚举声明体包含零个或多个值,称为枚举用例,还可包含任意数量的声明,包括计算型属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor。枚举声明不能包含析构器或者协议声明。
|
||||
|
||||
枚举类型可以采纳任意数量的协议,但是枚举不能从类、结构体和其他枚举继承。
|
||||
|
||||
@ -894,7 +910,7 @@ struct 结构体名称: 采纳的协议 {
|
||||
}
|
||||
```
|
||||
|
||||
结构体内可包含零个或多个声明。这些声明可以包括存储型和计算型属性、类型属性、实例方法、类型方法、构造器、下标、类型别名,甚至其他结构体、类、和枚举声明。结构体声明不能包含析构器或者协议声明。关于结构体的详细讨论和示例,请参阅 [类和结构体](../02_language_guide/09_Structures_And_Classes.md)。
|
||||
结构体内可包含零个或多个声明。这些声明可以包括存储型和计算型属性、类型属性、实例方法、类型方法、构造器、下标、类型别名,甚至其他结构体、类、actor 和枚举声明。结构体声明不能包含析构器或者协议声明。关于结构体的详细讨论和示例,请参阅 [类和结构体](../02_language_guide/09_Structures_And_Classes.md)。
|
||||
|
||||
结构体可以采纳任意数量的协议,但是不能继承自类、枚举或者其他结构体。
|
||||
|
||||
@ -956,7 +972,7 @@ class 类名: 超类, 采纳的协议 {
|
||||
}
|
||||
```
|
||||
|
||||
类内可以包含零个或多个声明。这些声明可以包括存储型和计算型属性、实例方法、类型方法、构造器、唯一的析构器、下标、类型别名,甚至其他结构体、类和枚举声明。类声明不能包含协议声明。关于类的详细讨论和示例,请参阅 [类和结构体](../02_language_guide/09_Structures_And_Classes.md)。
|
||||
类内可以包含零个或多个声明。这些声明可以包括存储型和计算型属性、实例方法、类型方法、构造器、唯一的析构器、下标、类型别名,甚至其他类、结构体、actor 和枚举声明。类声明不能包含协议声明。关于类的详细讨论和示例,请参阅 [类和结构体](../02_language_guide/09_Structures_And_Classes.md)。
|
||||
|
||||
一个类只能继承自一个超类,但是可以采纳任意数量的协议。超类紧跟在类名和冒号后面,其后跟着采纳的协议。泛型类可以继承自其它泛型类和非泛型类,但是非泛型类只能继承自其它非泛型类。当在冒号后面写泛型超类的名称时,必须写上泛型类的全名,包括它的泛型形参子句。
|
||||
|
||||
@ -976,7 +992,7 @@ class 类名: 超类, 采纳的协议 {
|
||||
|
||||
类实例属性可以用点语法(`.`)来访问,请参阅 [访问属性](../02_language_guide/09_Structures_And_Classes.md#accessing-properties)。
|
||||
|
||||
类是引用类型。当被赋予常量或变量,或者传递给函数作为参数时,类的实例会被引用,而不是被复制。关于引用类型的更多信息,请参阅 [结构体和枚举是值类型](../02_language_guide/09_Structures_And_Classes.md#structures-and-enumerations-are-value-types)。
|
||||
类是引用类型。当被赋予常量或变量,或者传递给函数作为参数时,类的实例会被引用,而不是被复制。关于引用类型的更多信息,请参阅 [类是引用类型](../02_language_guide/09_Structures_And_Classes.md#classes-are-reference-types)。
|
||||
|
||||
可以使用扩展声明来扩展类的行为,请参阅 [扩展声明](#extension-declaration)。
|
||||
|
||||
@ -1011,6 +1027,37 @@ class 类名: 超类, 采纳的协议 {
|
||||
> *类成员* → [声明](#declaration) | [编译控制流语句](./05_Statements.md#compiler-control-statement)
|
||||
>
|
||||
|
||||
## Actor 声明 {#actor-declaration}
|
||||
可以在程序中使用 *actor 声明(actor declaration)* 来引入一个 actor。Actor 声明使用关键字 `actor`,遵循如下的形式:
|
||||
|
||||
```swift
|
||||
actor 名称: 遵循的协议 {
|
||||
多条声明
|
||||
}
|
||||
```
|
||||
|
||||
Actor 内可包含零个或多个声明。这些声明包括存储属性和计算属性、实例方法、类型方法、构造器、唯一的析构器、下标、类型别名,甚至其他类、结构体和枚举声明。关于包含多种声明的 actors 的几种例子,请参考 [Actors](../02_language_guide/28_Concurrency.md#Actors)。
|
||||
|
||||
Actor 类型可以遵循任意数量的协议,但是不能继承于其他类、枚举、结构体或者其他 actor。但是用 `@objc` 标记的 actor 隐性地遵循了 `NSObjectProtocol` 协议,且作为 `NSObject` 的子类型暴露给 Objective-C 运行时。
|
||||
|
||||
有两种方法来创建声明过的 actor:
|
||||
* 如 [构造器](../02_language_guide/14_Initialization.md#initializers) 中所述,调用 actor 的构造器。
|
||||
* 如 [默认构造器](../02_language_guide/14_Initialization.md#default-initializers) 中所述,如果没有定义构造器,调用 actor 的默认构造器,actor 声明的所有属性会有默认值。
|
||||
|
||||
默认情况下,actor 里的成员变量(方法)是与 actor 隔离的。某个函数内的代码或者某个属性 getter 的代码是在 actor 中执行的。由于这些代码已经在同一个 actor 中运行,所以 actor 内部的代码可以与之同步地交互。但 actor 外部的代码必须用 `await` 标记 actor 内部的代码,以表示这段代码正在另一个 actor 中异步执行。关键路径无法引用 actor 中的隔离成员。Actor 隔离的存储属性能以输入输出参数的方式传递给同步函数,而不能传递给异步函数。
|
||||
|
||||
Actor 也有非隔离的成员变量(方法),这些成员变量(方法)以 `nonisolated` 关键字标记。非隔离的成员变量(方法)执行起来像 actor 外部的代码:它无法与 actor 任意一个隔离状态交互,而且使用时也无需用 `await` 标记。
|
||||
|
||||
Actor 的成员变量(方法)只有是异步状态或非隔离状态时, 才能用 `@objc` 修饰符标记。
|
||||
|
||||
初始化 actor 所声明的属性的过程在 [构造过程](../02_language_guide/14_Initialization.md) 一章中有说明。
|
||||
|
||||
如 [属性访问](../02_language_guide/09_Structures_And_Classes.md#accessing-properties) 中所述,actor 实例的属性可以通过使用点语法(.)的方式来访问到。
|
||||
|
||||
Actor 是引用类型;当被赋值给变量或常量,以及作为参数传递给函数调用时,actor 的实例会被引用,而不是被复制。关于引用类型的更多信息,请参阅 [类是引用类型](../02_language_guide/09_Structures_And_Classes.md#classes-are-reference-types)。
|
||||
|
||||
可以使用扩展声明来扩展 actor 类型的行为,请参阅 [扩展声明](#extension-declaration)。
|
||||
|
||||
## 协议声明 {#protocol-declaration}
|
||||
*协议声明(protocol declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
||||
|
||||
@ -1074,9 +1121,11 @@ protocol SomeProtocol: AnyObject {
|
||||
> *协议主体* → **{** [协议成员声明列表](#protocol-member-declarations)<sub>可选</sub> **}**
|
||||
>
|
||||
>
|
||||
#### protocol-members {#protocol-members}
|
||||
>
|
||||
> *协议多个成员* → [协议成员](#protocol-member) [协议多个成员](#protocol-members)<sub>可选</sub>
|
||||
>
|
||||
>
|
||||
>
|
||||
#### protocol-member {#protocol-member}
|
||||
>
|
||||
> *协议成员* → [协议成员声明](#protocol-member-declaration) | [编译控制流语句](./05_Statements.md#compiler-control-statement)
|
||||
@ -1095,11 +1144,8 @@ protocol SomeProtocol: AnyObject {
|
||||
>
|
||||
> *协议成员声明* → [协议关联类型声明](#protocol-associated-type-declaration)
|
||||
>
|
||||
>
|
||||
#### protocol-member-declarations {#protocol-member-declarations}
|
||||
>
|
||||
> *协议成员声明列表* → [协议成员声明](#protocol-member-declaration) [协议成员声明列表](#protocol-member-declarations)<sub>可选</sub>
|
||||
>
|
||||
> *协议成员声明* → [类型别名声明](#type-alias-declaration)
|
||||
>
|
||||
|
||||
### 协议属性声明 {#protocol-property-declaration}
|
||||
协议可以通过在协议声明主体中引入一个协议属性声明,来声明符合的类型必须实现的属性。协议属性声明有一种特殊的变量声明形式:
|
||||
@ -1707,11 +1753,11 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
||||
>
|
||||
|
||||
#### precedence-group-declaration {#precedence-group-declaration}
|
||||
> *优先级组声明* → **precedence**[优先级组名称](#precedence-group-name){[多优先级组属性](#precedence-group-attributes)<sub>可选</sub> }
|
||||
> *优先级组声明* → **precedencegroup** [优先级组名称](#precedence-group-name) **{** [多优先级组属性](#precedence-group-attributes)<sub>可选</sub> **}**
|
||||
>
|
||||
|
||||
#### precedence-group-attributes {#precedence-group-attributes}
|
||||
> *优先级组属性* → [优先级组属性](#precedence-group-attribute)[多优先级组属性](#precedence-group-attributes)<sub>可选</sub> **{** **}**
|
||||
> *优先级组属性* → [优先级组属性](#precedence-group-attribute) [多优先级组属性](#precedence-group-attributes)<sub>可选</sub>
|
||||
>
|
||||
|
||||
#### precedence-group-attribute {#precedence-group-attribute}
|
||||
@ -1724,30 +1770,30 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
||||
>
|
||||
#### precedence-group-relation {#precedence-group-relation}
|
||||
>
|
||||
> *优先级组关系* → **higherThan:**[多优先级组名称](#precedence-group-names)
|
||||
> *优先级组关系* → **higherThan** **:** [多优先级组名称](#precedence-group-names)
|
||||
>
|
||||
> *优先级组关系* → **lowerThan:**[多优先级组名称](#precedence-group-names)
|
||||
> *优先级组关系* → **lowerThan** **:** [多优先级组名称](#precedence-group-names)
|
||||
>
|
||||
>
|
||||
#### precedence-group-assignment {#precedence-group-assignment}
|
||||
>
|
||||
> *优先级组赋值* → **assignment:**[布尔字面值](./02_Lexical_Structure.md#boolean-literal)
|
||||
> *优先级组赋值* → **assignment** **:** [布尔字面值](./02_Lexical_Structure.md#boolean-literal)
|
||||
>
|
||||
|
||||
#### precedence-group-associativity {#precedence-group-associativity}
|
||||
> *优先级组结合性* → **associativity:left**
|
||||
> *优先级组结合性* → **associativity** **:** **left**
|
||||
>
|
||||
> *优先级组结合性* → **associativity:right**
|
||||
> *优先级组结合性* → **associativity** **:** **right**
|
||||
>
|
||||
> *优先级组结合性* → **associativity:none**
|
||||
> *优先级组结合性* → **associativity** **:** **none**
|
||||
>
|
||||
|
||||
#### precedence-group-names {#precedence-group-names}
|
||||
> *多优先级组名称* → [优先级组名称](#precedence-group-name) | [优先级组名称](#precedence-group-name) | [优先级组名称](#precedence-group-name)
|
||||
> *多优先级组名称* → [优先级组名称](#precedence-group-name) | [优先级组名称](#precedence-group-name) **,** [多优先级组名称](#precedence-group-names)
|
||||
>
|
||||
|
||||
#### precedence-group-name {#precedence-group-name}
|
||||
> *优先级组名称* →[标识符](./02_Lexical_Structure.md#identifier)
|
||||
> *优先级组名称* → [标识符](./02_Lexical_Structure.md#identifier)
|
||||
>
|
||||
|
||||
## 声明修饰符 {#Declaration-Modifiers}
|
||||
@ -1802,20 +1848,30 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
||||
该修饰符用于修饰变量或存储型变量属性,表示该变量或属性持有其存储的对象的弱引用。这种变量或属性的类型必须是可选的类类型。使用 `weak` 修饰符可避免强引用循环。关于 `weak` 修饰符的更多信息和例子,请参阅 [弱引用](../02_language_guide/24_Automatic_Reference_Counting.md#resolving-strong-reference-cycles-between-class-instances)。
|
||||
|
||||
### 访问控制级别 {#access-control-levels}
|
||||
Swift 提供了三个级别的访问控制:`public`、`internal` 和 `private`。可以使用以下任意一种访问级别修饰符来指定声明的访问级别。访问控制在 [访问控制](../02_language_guide/26_Access_Control.md) 中有详细讨论。
|
||||
Swift 提供了五个级别的访问控制:`open`、`public`、`internal`、`file private` 和 `private`。可以使用以下任意一种访问级别修饰符来指定声明的访问级别。访问控制在 [访问控制](../02_language_guide/26_Access_Control.md) 中有详细讨论。
|
||||
|
||||
`open`
|
||||
|
||||
该修饰符表示声明可被同模块的代码访问,且可作为基类使用,只要其他模块导入了声明所在的模块,也可以进行访问,且可作为基类使用。
|
||||
|
||||
`public`
|
||||
|
||||
该修饰符表示声明可被同模块的代码访问,只要其他模块导入了声明所在的模块,也可以进行访问。
|
||||
该修饰符表示声明可被同模块的代码访问,且可作为基类使用,只要其他模块导入了声明所在的模块,也可以进行访问,但不可作为基类使用。
|
||||
|
||||
`internal`
|
||||
|
||||
该修饰符表示声明只能被同模块的代码访问。默认情况下,绝大多数声明会被隐式标记 `internal` 访问级别修饰符。
|
||||
|
||||
`private`
|
||||
`fileprivate`
|
||||
|
||||
该修饰符表示声明只能被所在源文件的代码访问。
|
||||
|
||||
`private`
|
||||
|
||||
该修饰符表示声明只能被声明所直接包含的作用域内的代码访问。
|
||||
|
||||
为了达到访问控制的目的,同一文件中相同类型的扩展共享访问控制作用域。如果这些扩展与它们扩展的类型也在同一个文件中,则这些扩展共享该类型的访问控制作用域。在类型声明中声明的私有成员可以从扩展中访问,在某个扩展中声明的私有成员可以从其他扩展和类型声明中访问。
|
||||
|
||||
以上访问级别修饰符都可以选择带上一个参数,该参数由一对圆括号和其中的 `set` 关键字组成(例如,`private(set)`)。使用这种形式的访问级别修饰符来限制某个属性或下标的 setter 的访问级别低于其本身的访问级别,正如 [Getter 和 Setter](../02_language_guide/26_Access_Control.md#getters-and-setters) 中所讨论的。
|
||||
|
||||
|
||||
@ -1824,19 +1880,34 @@ Swift 提供了三个级别的访问控制:`public`、`internal` 和 `private`
|
||||
>
|
||||
|
||||
#### declaration-modifier {#declaration-modifier}
|
||||
> *声明修饰符* → **class** | **convenience**| **dynamic** | **final** | **infix** | **lazy** | **mutating** | **nonmutating** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
|
||||
> *声明修饰符* → **class** | **convenience** | **dynamic** | **final** | **infix** | **lazy** | **optional** | **override** | **postfix** | **prefix** | **required** | **static** | **unowned** | **unowned ( safe )** | **unowned ( unsafe )** | **weak**
|
||||
>
|
||||
> 声明修饰符 → [访问级别修饰符](#access-level-modifier)
|
||||
>
|
||||
> 声明修饰符 → [可变修饰符](#mutation-modifier)
|
||||
>
|
||||
> 声明修饰符 → [actor 隔离修饰符](#actor-isolation-modifier)
|
||||
>
|
||||
#### declaration-modifiers {#declaration-modifiers}
|
||||
>
|
||||
> *声明修饰符列表* → [声明修饰符](#declaration-modifier) [声明修饰符列表](#declaration-modifiers)<sub>可选</sub>
|
||||
|
||||
#### access-level-modifier {#access-level-modifier}
|
||||
> 访问级别修饰符 → **internal** | **internal ( set )**
|
||||
>
|
||||
> 访问级别修饰符 → **private** | **private ( set )**
|
||||
>
|
||||
> 访问级别修饰符 → **fileprivate** | **fileprivate ( set )**
|
||||
>
|
||||
> 访问级别修饰符 → **internal** | **internal ( set )**
|
||||
>
|
||||
> 访问级别修饰符 → **public** | **public ( set )**
|
||||
>
|
||||
> 访问级别修饰符 → **open** | **open ( set )**
|
||||
>
|
||||
|
||||
#### mutation-modifier {#mutation-modifier}
|
||||
> 可变修饰符 → **mutating** | **nonmutating**
|
||||
>
|
||||
|
||||
#### actor-isolation-modifier {#actor-isolation-modifier}
|
||||
> actor 隔离修饰符 → **nonisolated**
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user