Compare commits
22 Commits
feature/Ch
...
Ch-Declara
| Author | SHA1 | Date | |
|---|---|---|---|
| c70d3aa08f | |||
| 5c54284a30 | |||
| ec01e5ad58 | |||
| afc5008c29 | |||
| c7644e869a | |||
| 3d7dfe15d7 | |||
| 2d05380f78 | |||
| 54c13df117 | |||
| 10f7e8f9a2 | |||
| ff3824c368 | |||
| c59ffce41e | |||
| 80c2ac750d | |||
| 704d910495 | |||
| 0ab60a97c3 | |||
| f43cb3fdb9 | |||
| 872d7af8a3 | |||
| 24d88f684a | |||
| a15735f51b | |||
| aba2a5fb55 | |||
| 096f2acfc4 | |||
| 8b99054c0c | |||
| d9d2952e85 |
Binary file not shown.
BIN
document/TheSwiftProgrammingLanguageSwift55.epub
Normal file
BIN
document/TheSwiftProgrammingLanguageSwift55.epub
Normal file
Binary file not shown.
@ -114,7 +114,7 @@ print("\(numberOfChoices) beverages available")
|
|||||||
// 打印“3 beverages available”
|
// 打印“3 beverages available”
|
||||||
```
|
```
|
||||||
|
|
||||||
在前面的例子中,通过 `Beverage.allCases` 可以访问到包含 `Beverage` 枚举所有成员的集合。`allCases` 的使用方法和其它一般集合一样——集合中的元素是枚举类型的实例,所以在上面的情况中,这些元素是 `Beverage` 值。在前面的例子中,统计了总共有多少个枚举成员。而在下面的例子中,则使用 `for` 循环来遍历所有枚举成员。
|
在前面的例子中,通过 `Beverage.allCases` 可以访问到包含 `Beverage` 枚举所有成员的集合。`allCases` 的使用方法和其它一般集合一样——集合中的元素是枚举类型的实例,所以在上面的情况中,这些元素是 `Beverage` 值。在前面的例子中,统计了总共有多少个枚举成员。而在下面的例子中,则使用 `for-in` 循环来遍历所有枚举成员。
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
for beverage in Beverage.allCases {
|
for beverage in Beverage.allCases {
|
||||||
|
|||||||
@ -32,6 +32,10 @@ Swift 中结构体和类有很多共同点。两者都可以:
|
|||||||
|
|
||||||
类支持的附加功能是以增加复杂性为代价的。作为一般准则,优先使用结构体,因为它们更容易理解,仅在适当或必要时才使用类。实际上,这意味着你的大多数自定义数据类型都会是结构体和枚举。更多详细的比较参见 [在结构和类之间进行选择](https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes)。
|
类支持的附加功能是以增加复杂性为代价的。作为一般准则,优先使用结构体,因为它们更容易理解,仅在适当或必要时才使用类。实际上,这意味着你的大多数自定义数据类型都会是结构体和枚举。更多详细的比较参见 [在结构和类之间进行选择](https://developer.apple.com/documentation/swift/choosing_between_structures_and_classes)。
|
||||||
|
|
||||||
|
> 注意
|
||||||
|
>
|
||||||
|
> 类和 actors 共享很多特性。更多信息请参见 [并发](./28_Concurrency.md)。
|
||||||
|
|
||||||
### 类型定义的语法 {#definition-syntax}
|
### 类型定义的语法 {#definition-syntax}
|
||||||
|
|
||||||
结构体和类有着相似的定义方式。你通过 `struct` 关键字引入结构体,通过 `class` 关键字引入类,并将它们的具体定义放在一对大括号中:
|
结构体和类有着相似的定义方式。你通过 `struct` 关键字引入结构体,通过 `class` 关键字引入类,并将它们的具体定义放在一对大括号中:
|
||||||
|
|||||||
@ -1036,7 +1036,7 @@ class SomeClass {
|
|||||||
```swift
|
```swift
|
||||||
struct Chessboard {
|
struct Chessboard {
|
||||||
let boardColors: [Bool] = {
|
let boardColors: [Bool] = {
|
||||||
var temporaryBoard = [Bool]()
|
var temporaryBoard: [Bool] = []
|
||||||
var isBlack = false
|
var isBlack = false
|
||||||
for i in 1...8 {
|
for i in 1...8 {
|
||||||
for j in 1...8 {
|
for j in 1...8 {
|
||||||
|
|||||||
@ -97,7 +97,7 @@ class Person {
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
class Residence {
|
class Residence {
|
||||||
var rooms = [Room]()
|
var rooms: [Room] = []
|
||||||
var numberOfRooms: Int {
|
var numberOfRooms: Int {
|
||||||
return rooms.count
|
return rooms.count
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,7 +141,7 @@ Swift 为不确定类型提供了两种特殊的类型别名:
|
|||||||
这里有个示例,使用 `Any` 类型来和混合的不同类型一起工作,包括函数类型和非类类型。它创建了一个可以存储 `Any` 类型的数组 `things`:
|
这里有个示例,使用 `Any` 类型来和混合的不同类型一起工作,包括函数类型和非类类型。它创建了一个可以存储 `Any` 类型的数组 `things`:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
var things = [Any]()
|
var things: [Any] = []
|
||||||
|
|
||||||
things.append(0)
|
things.append(0)
|
||||||
things.append(0.0)
|
things.append(0.0)
|
||||||
|
|||||||
@ -135,7 +135,7 @@ swapTwoValues(&someString, &anotherString)
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
struct IntStack {
|
struct IntStack {
|
||||||
var items = [Int]()
|
var items: [Int] = []
|
||||||
mutating func push(_ item: Int) {
|
mutating func push(_ item: Int) {
|
||||||
items.append(item)
|
items.append(item)
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ struct IntStack {
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
struct Stack<Element> {
|
struct Stack<Element> {
|
||||||
var items = [Element]()
|
var items: [Element] = []
|
||||||
mutating func push(_ item: Element) {
|
mutating func push(_ item: Element) {
|
||||||
items.append(item)
|
items.append(item)
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ protocol Container {
|
|||||||
```swift
|
```swift
|
||||||
struct IntStack: Container {
|
struct IntStack: Container {
|
||||||
// IntStack 的原始实现部分
|
// IntStack 的原始实现部分
|
||||||
var items = [Int]()
|
var items: [Int] = []
|
||||||
mutating func push(_ item: Int) {
|
mutating func push(_ item: Int) {
|
||||||
items.append(item)
|
items.append(item)
|
||||||
}
|
}
|
||||||
@ -386,7 +386,7 @@ struct IntStack: Container {
|
|||||||
```swift
|
```swift
|
||||||
struct Stack<Element>: Container {
|
struct Stack<Element>: Container {
|
||||||
// Stack<Element> 的原始实现部分
|
// Stack<Element> 的原始实现部分
|
||||||
var items = [Element]()
|
var items: [Element] = []
|
||||||
mutating func push(_ item: Element) {
|
mutating func push(_ item: Element) {
|
||||||
items.append(item)
|
items.append(item)
|
||||||
}
|
}
|
||||||
@ -721,7 +721,7 @@ protocol ComparableContainer: Container where Item: Comparable { }
|
|||||||
extension Container {
|
extension Container {
|
||||||
subscript<Indices: Sequence>(indices: Indices) -> [Item]
|
subscript<Indices: Sequence>(indices: Indices) -> [Item]
|
||||||
where Indices.Iterator.Element == Int {
|
where Indices.Iterator.Element == Int {
|
||||||
var result = [Item]()
|
var result: [Item] = []
|
||||||
for index in indices {
|
for index in indices {
|
||||||
result.append(self[index])
|
result.append(self[index])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ print("We're number \(one)!")
|
|||||||
>
|
>
|
||||||
> 如果你写过并发和多线程的代码,内存访问冲突也许是同样的问题。然而,这里访问冲突的讨论是在单线程的情境下讨论的,并没有使用并发或者多线程。
|
> 如果你写过并发和多线程的代码,内存访问冲突也许是同样的问题。然而,这里访问冲突的讨论是在单线程的情境下讨论的,并没有使用并发或者多线程。
|
||||||
>
|
>
|
||||||
> 如果你曾经在单线程代码里有访问冲突,Swift 可以保证你在编译或者运行时会得到错误。对于多线程的代码,可以使用 [Thread Sanitizer](https://developer.apple.com/documentation/code_diagnostics/thread_sanitizer) 去帮助检测多线程的冲突。
|
> 如果你曾经在单线程代码里有访问冲突,Swift 可以保证你在编译或者运行时会得到错误。对于多线程的代码,可以使用 [Thread Sanitizer](https://developer.apple.com/documentation/xcode/diagnosing_memory_thread_and_crash_issues_early) 去帮助检测多线程的冲突。
|
||||||
|
|
||||||
### 内存访问性质 {#characteristics-of-memory-access}
|
### 内存访问性质 {#characteristics-of-memory-access}
|
||||||
|
|
||||||
|
|||||||
1
source/02_language_guide/28_Concurrency.md
Normal file
1
source/02_language_guide/28_Concurrency.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# 并发
|
||||||
@ -6,7 +6,7 @@ Swift 的*“词法结构(lexical structure)”* 描述了能构成该语言
|
|||||||
|
|
||||||
## 空白与注释 {#whitespace}
|
## 空白与注释 {#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)。多行注释由 `/*` 开始,以 `*/` 结束。多行注释允许嵌套,但注释标记必须成对出现。
|
注释被编译器当作空白处理。单行注释由 `//` 开始直至遇到换行符(U+000A)或者回车符(U+000D)。多行注释由 `/*` 开始,以 `*/` 结束。多行注释允许嵌套,但注释标记必须成对出现。
|
||||||
|
|
||||||
|
|||||||
@ -129,7 +129,7 @@ someTuple = (left: 5, right: 5) // 错误:命名类型不匹配
|
|||||||
|
|
||||||
你可以对形参类型为 `() -> T`(其中 T 是任何类型)的函数使用 `autoclosure` 特性,这会在调用侧隐式创建一个闭包。这从语法结构上提供了一种便捷:延迟对表达式的求值,直到其值在函数体中被调用。以自动闭包做为形参的函数类型的例子详见 [自动闭包](../02_language_guide/07_Closures.md#autoclosures)。
|
你可以对形参类型为 `() -> 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)。
|
为了指定一个 `in-out` 参数,可以在形参类型前加 `inout` 前缀。但是你不可以对可变参数或返回值类型使用 `inout`。关于这种形参的详细讲解请参阅 [输入输出参数](../02_language_guide/06_Functions.md#in-out-parameters)。
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,8 @@
|
|||||||
>
|
>
|
||||||
> *声明* → [类声明](#class-declaration)
|
> *声明* → [类声明](#class-declaration)
|
||||||
>
|
>
|
||||||
|
> *声明* → [actor 声明](#actor-declaration)
|
||||||
|
>
|
||||||
> *声明* → [协议声明](#protocol-declaration)
|
> *声明* → [协议声明](#protocol-declaration)
|
||||||
>
|
>
|
||||||
> *声明* → [构造器声明](#initializer-declaration)
|
> *声明* → [构造器声明](#initializer-declaration)
|
||||||
@ -481,7 +483,7 @@ repeatGreeting("Hello, world!", count: 2) // count 有标签, greeting 没有
|
|||||||
|
|
||||||
更多关于内存安全和内存独占权的讨论,请参阅 [内存安全](../02_language_guide/24_Memory_Safety.md)。
|
更多关于内存安全和内存独占权的讨论,请参阅 [内存安全](../02_language_guide/24_Memory_Safety.md)。
|
||||||
|
|
||||||
如果一个闭包或者嵌套函数捕获了一个输入输出参数,那么这个闭包或者嵌套函数必须是非逃逸的。如果你需要捕获一个输入输出参数,但并不对其进行修改或者在其他代码中观察其值变化,那么你可以使用捕获列表来显式地表明这是个不可变捕获。
|
如果一个闭包或者嵌套函数捕获了一个输入输出参数,那么这个闭包或者嵌套函数必须是非逃逸的。如果你需要捕获一个输入输出参数,但并不对其进行修改,那么你可以使用捕获列表来显式地表明这是个不可变捕获。
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func someFunction(a: inout Int) -> () -> Int {
|
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:)
|
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}
|
### 抛出错误的函数和方法 {#throwing-functions-and-methods}
|
||||||
可以抛出错误的函数或方法必须使用 `throws` 关键字标记。这类函数和方法被称为抛出函数和抛出方法。它们有着下面的形式:
|
可以抛出错误的函数或方法必须使用 `throws` 关键字标记。这类函数和方法被称为抛出函数和抛出方法。它们有着下面的形式:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func 函数名称(参数列表) throws -> 返回类型 {
|
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}
|
### 永不返回的函数 {#functions-that-never-return}
|
||||||
Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它的调用者。`Never` 返回类型的函数或方法可以称为不归,不归函数、方法要么引发不可恢复的错误,要么永远不停地运作,这会使调用后本应执行得代码就不再执行了。但即使是不归函数、方法,抛错函数和重抛出函数也可以将程序控制转移到合适的 `catch` 代码块。
|
Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它的调用者。`Never` 返回类型的函数或方法可以称为不归,不归函数、方法要么引发不可恢复的错误,要么永远不停地运作,这会使调用后本应执行得代码就不再执行了。但即使是不归函数、方法,抛错函数和重抛出函数也可以将程序控制转移到合适的 `catch` 代码块。
|
||||||
@ -644,9 +660,9 @@ Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它
|
|||||||
#### function-signature {#function-signature}
|
#### 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}
|
#### function-result {#function-result}
|
||||||
@ -697,7 +713,7 @@ Swift 定义了 `Never` 类型,它表示函数或者方法不会返回给它
|
|||||||
## 枚举声明 {#enumeration-declaration}
|
## 枚举声明 {#enumeration-declaration}
|
||||||
在程序中使用*枚举声明(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#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)。
|
可以使用扩展声明来扩展类的行为,请参阅 [扩展声明](#extension-declaration)。
|
||||||
|
|
||||||
@ -1011,6 +1027,37 @@ class 类名: 超类, 采纳的协议 {
|
|||||||
> *类成员* → [声明](#declaration) | [编译控制流语句](./05_Statements.md#compiler-control-statement)
|
> *类成员* → [声明](#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 declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
*协议声明(protocol declaration)* 可以为程序引入一个命名的协议类型。协议声明只能在全局区域使用 `protocol` 关键字来进行声明,并遵循如下形式:
|
||||||
|
|
||||||
@ -1074,6 +1121,8 @@ protocol SomeProtocol: AnyObject {
|
|||||||
> *协议主体* → **{** [协议成员声明列表](#protocol-member-declarations)<sub>可选</sub> **}**
|
> *协议主体* → **{** [协议成员声明列表](#protocol-member-declarations)<sub>可选</sub> **}**
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
#### protocol-members {#protocol-members}
|
||||||
|
>
|
||||||
> *协议多个成员* → [协议成员](#protocol-member) [协议多个成员](#protocol-members)<sub>可选</sub>
|
> *协议多个成员* → [协议成员](#protocol-member) [协议多个成员](#protocol-members)<sub>可选</sub>
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
@ -1095,10 +1144,7 @@ protocol SomeProtocol: AnyObject {
|
|||||||
>
|
>
|
||||||
> *协议成员声明* → [协议关联类型声明](#protocol-associated-type-declaration)
|
> *协议成员声明* → [协议关联类型声明](#protocol-associated-type-declaration)
|
||||||
>
|
>
|
||||||
>
|
> *协议成员声明* → [类型别名声明](#type-alias-declaration)
|
||||||
#### protocol-member-declarations {#protocol-member-declarations}
|
|
||||||
>
|
|
||||||
> *协议成员声明列表* → [协议成员声明](#protocol-member-declaration) [协议成员声明列表](#protocol-member-declarations)<sub>可选</sub>
|
|
||||||
>
|
>
|
||||||
|
|
||||||
### 协议属性声明 {#protocol-property-declaration}
|
### 协议属性声明 {#protocol-property-declaration}
|
||||||
@ -1707,11 +1753,11 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
|||||||
>
|
>
|
||||||
|
|
||||||
#### precedence-group-declaration {#precedence-group-declaration}
|
#### 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-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}
|
#### precedence-group-attribute {#precedence-group-attribute}
|
||||||
@ -1724,26 +1770,26 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
|||||||
>
|
>
|
||||||
#### precedence-group-relation {#precedence-group-relation}
|
#### 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}
|
#### 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}
|
#### 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-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}
|
#### precedence-group-name {#precedence-group-name}
|
||||||
@ -1802,20 +1848,30 @@ Swift 定义了大量的优先级组来与标准库的运算符配合使用,
|
|||||||
该修饰符用于修饰变量或存储型变量属性,表示该变量或属性持有其存储的对象的弱引用。这种变量或属性的类型必须是可选的类类型。使用 `weak` 修饰符可避免强引用循环。关于 `weak` 修饰符的更多信息和例子,请参阅 [弱引用](../02_language_guide/24_Automatic_Reference_Counting.md#resolving-strong-reference-cycles-between-class-instances)。
|
该修饰符用于修饰变量或存储型变量属性,表示该变量或属性持有其存储的对象的弱引用。这种变量或属性的类型必须是可选的类类型。使用 `weak` 修饰符可避免强引用循环。关于 `weak` 修饰符的更多信息和例子,请参阅 [弱引用](../02_language_guide/24_Automatic_Reference_Counting.md#resolving-strong-reference-cycles-between-class-instances)。
|
||||||
|
|
||||||
### 访问控制级别 {#access-control-levels}
|
### 访问控制级别 {#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`
|
`public`
|
||||||
|
|
||||||
该修饰符表示声明可被同模块的代码访问,只要其他模块导入了声明所在的模块,也可以进行访问。
|
该修饰符表示声明可被同模块的代码访问,且可作为基类使用,只要其他模块导入了声明所在的模块,也可以进行访问,但不可作为基类使用。
|
||||||
|
|
||||||
`internal`
|
`internal`
|
||||||
|
|
||||||
该修饰符表示声明只能被同模块的代码访问。默认情况下,绝大多数声明会被隐式标记 `internal` 访问级别修饰符。
|
该修饰符表示声明只能被同模块的代码访问。默认情况下,绝大多数声明会被隐式标记 `internal` 访问级别修饰符。
|
||||||
|
|
||||||
`private`
|
`fileprivate`
|
||||||
|
|
||||||
该修饰符表示声明只能被所在源文件的代码访问。
|
该修饰符表示声明只能被所在源文件的代码访问。
|
||||||
|
|
||||||
|
`private`
|
||||||
|
|
||||||
|
该修饰符表示声明只能被声明所直接包含的作用域内的代码访问。
|
||||||
|
|
||||||
|
为了达到访问控制的目的,同一文件中相同类型的扩展共享访问控制作用域。如果这些扩展与它们扩展的类型也在同一个文件中,则这些扩展共享该类型的访问控制作用域。在类型声明中声明的私有成员可以从扩展中访问,在某个扩展中声明的私有成员可以从其他扩展和类型声明中访问。
|
||||||
|
|
||||||
以上访问级别修饰符都可以选择带上一个参数,该参数由一对圆括号和其中的 `set` 关键字组成(例如,`private(set)`)。使用这种形式的访问级别修饰符来限制某个属性或下标的 setter 的访问级别低于其本身的访问级别,正如 [Getter 和 Setter](../02_language_guide/26_Access_Control.md#getters-and-setters) 中所讨论的。
|
以上访问级别修饰符都可以选择带上一个参数,该参数由一对圆括号和其中的 `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}
|
#### 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)
|
> 声明修饰符 → [访问级别修饰符](#access-level-modifier)
|
||||||
>
|
>
|
||||||
|
> 声明修饰符 → [可变修饰符](#mutation-modifier)
|
||||||
|
>
|
||||||
|
> 声明修饰符 → [actor 隔离修饰符](#actor-isolation-modifier)
|
||||||
>
|
>
|
||||||
#### declaration-modifiers {#declaration-modifiers}
|
#### declaration-modifiers {#declaration-modifiers}
|
||||||
>
|
>
|
||||||
> *声明修饰符列表* → [声明修饰符](#declaration-modifier) [声明修饰符列表](#declaration-modifiers)<sub>可选</sub>
|
> *声明修饰符列表* → [声明修饰符](#declaration-modifier) [声明修饰符列表](#declaration-modifiers)<sub>可选</sub>
|
||||||
|
|
||||||
#### access-level-modifier {#access-level-modifier}
|
#### access-level-modifier {#access-level-modifier}
|
||||||
> 访问级别修饰符 → **internal** | **internal ( set )**
|
|
||||||
>
|
|
||||||
> 访问级别修饰符 → **private** | **private ( set )**
|
> 访问级别修饰符 → **private** | **private ( set )**
|
||||||
>
|
>
|
||||||
|
> 访问级别修饰符 → **fileprivate** | **fileprivate ( set )**
|
||||||
|
>
|
||||||
|
> 访问级别修饰符 → **internal** | **internal ( set )**
|
||||||
|
>
|
||||||
> 访问级别修饰符 → **public** | **public ( set )**
|
> 访问级别修饰符 → **public** | **public ( set )**
|
||||||
>
|
>
|
||||||
|
> 访问级别修饰符 → **open** | **open ( set )**
|
||||||
|
>
|
||||||
|
|
||||||
|
#### mutation-modifier {#mutation-modifier}
|
||||||
|
> 可变修饰符 → **mutating** | **nonmutating**
|
||||||
|
>
|
||||||
|
|
||||||
|
#### actor-isolation-modifier {#actor-isolation-modifier}
|
||||||
|
> actor 隔离修饰符 → **nonisolated**
|
||||||
|
>
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
* [析构过程](02_language_guide/15_Deinitialization.md)
|
* [析构过程](02_language_guide/15_Deinitialization.md)
|
||||||
* [可选链](02_language_guide/16_Optional_Chaining.md)
|
* [可选链](02_language_guide/16_Optional_Chaining.md)
|
||||||
* [错误处理](02_language_guide/17_Error_Handling.md)
|
* [错误处理](02_language_guide/17_Error_Handling.md)
|
||||||
|
* [并发](02_language_guide/28_Concurrency.md)
|
||||||
* [类型转换](02_language_guide/18_Type_Casting.md)
|
* [类型转换](02_language_guide/18_Type_Casting.md)
|
||||||
* [嵌套类型](02_language_guide/19_Nested_Types.md)
|
* [嵌套类型](02_language_guide/19_Nested_Types.md)
|
||||||
* [扩展](02_language_guide/20_Extensions.md)
|
* [扩展](02_language_guide/20_Extensions.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user