From 054c06276f782308126d27ac21554365e020e80b Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 21:46:40 +0800 Subject: [PATCH 01/67] wip: Top-Level Code --- .../ReferenceManual/Declarations.md | 93 +++++++------------ 1 file changed, 32 insertions(+), 61 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 444706ba..7313a637 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -7,72 +7,43 @@ Swift 文档源文件地址:https://docs.swift.org/swift-book/documentation/th # Declarations Introduce types, operators, variables, and other names and constructs. +引入类型、运算符、变量以及其他名称和构造。 -A *declaration* introduces a new name or construct into your program. -For example, you use declarations to introduce functions and methods, -to introduce variables and constants, -and to define enumeration, structure, class, and protocol types. -You can also use a declaration to extend the behavior -of an existing named type and to import symbols into your program that are declared elsewhere. +一个*声明*将一个新名称或构造引入到你的程序中。例如,你使用声明来引入函数和方法,引入变量和常量,以及定义枚举、结构体、类和协议类型。你还可以使用声明来扩展现有具名类型的行为,并将其他地方声明的符号引入到你的程序中。 -In Swift, most declarations are also definitions in the sense that they're implemented -or initialized at the same time they're declared. That said, because protocols don't -implement their members, most protocol members are declarations only. For convenience -and because the distinction isn't that important in Swift, -the term *declaration* covers both declarations and definitions. +在 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* → *actor-declaration* \ -> *declaration* → *protocol-declaration* \ -> *declaration* → *initializer-declaration* \ -> *declaration* → *deinitializer-declaration* \ -> *declaration* → *extension-declaration* \ -> *declaration* → *subscript-declaration* \ -> *declaration* → *macro-declaration* \ -> *declaration* → *operator-declaration* \ -> *declaration* → *precedence-group-declaration* \ - -## Top-Level Code - -The top-level code in a Swift source file consists of zero or more statements, -declarations, and expressions. -By default, variables, constants, and other named declarations that are declared -at the top-level of a source file are accessible to code -in every source file that's part of the same module. -You can override this default behavior -by marking the declaration with an access-level modifier, -as described in . - -There are two kinds of top-level code: -top-level declarations and executable top-level code. -Top-level declarations consist of only declarations, -and are allowed in all Swift source files. -Executable top-level code contains statements and expressions, -not just declarations, -and is allowed only as the top-level entry point for the program. - -The Swift code you compile to make an executable -can contain at most one of the following approaches -to mark the top-level entry point, -regardless of how the code is organized into files and modules: -the `main` attribute, -the `NSApplicationMain` attribute, -the `UIApplicationMain` attribute, -a `main.swift` file, -or a file that contains top-level executable code. - -> Grammar of a top-level declaration: +> *声明* → *导入声明* +> *声明* → *常量声明* +> *声明* → *变量声明* +> *声明* → *类型别名声明* +> *声明* → *函数声明* +> *声明* → *枚举声明* +> *声明* → *结构体声明* +> *声明* → *类声明* +> *声明* → *actor 声明* +> *声明* → *协议声明* +> *声明* → *构造器声明* +> *声明* → *析构器声明* +> *声明* → *扩展声明* +> *声明* → *下标声明* +> *声明* → *宏声明* +> *声明* → *操作符声明* +> *声明* → *优先级组声明* + +## 顶级代码 + +Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他命名声明可以被同一模块中每个源文件的代码访问。您可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 [doc:Declarations#Access-Control-Levels](doc:Declarations#Access-Control-Levels)。 + +有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。 + +您编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。 + +> 顶级声明的语法: > -> *top-level-declaration* → *statements*_?_ +> *顶级声明* → *语句*_?_ ## Code Blocks From 8f0b178b5cdd66a517f6b36acdaa3fb9af01e398 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 21:51:02 +0800 Subject: [PATCH 02/67] wip: code blocks --- swift-6-beta.docc/ReferenceManual/Declarations.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 7313a637..236639d5 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -45,11 +45,9 @@ Swift 源文件中的顶级代码由零个或多个语句、声明和表达式 > > *顶级声明* → *语句*_?_ -## Code Blocks +## 代码块 -A *code block* is used by a variety of declarations and control structures -to group statements together. -It has the following form: +一个*代码块*被各种声明和控制结构用来将语句组合在一起。它具有以下形式: ```swift { @@ -57,10 +55,7 @@ It has the following form: } ``` -The *statements* inside a code block include declarations, -expressions, and other kinds of statements and are executed in order -of their appearance in source code. - +代码块中的*语句*包括声明、表达式和其他类型的语句,并按它们在源代码中出现的顺序执行。 @@ -69,9 +64,9 @@ of their appearance in source code. TODO: Discuss scope. I assume a code block creates a new scope? --> -> Grammar of a code block: +> 代码块的语法: > -> *code-block* → **`{`** *statements*_?_ **`}`** +> *代码块* → **`{`** *语句*_?_ **`}`** ## Import Declaration From d804fb7626c04e10bbe2c968582ee6c7b82600e6 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:00:15 +0800 Subject: [PATCH 03/67] wip: Import Declaration --- .../ReferenceManual/Declarations.md | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 236639d5..fb44a2e7 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -70,22 +70,13 @@ Swift 源文件中的顶级代码由零个或多个语句、声明和表达式 ## Import Declaration -An *import declaration* lets you access symbols -that are declared outside the current file. -The basic form imports the entire module; -it consists of the `import` keyword followed by a module name: +一个*导入声明*让你访问在当前文件外部声明的符号。基本形式导入整个模块;它由 `import` 关键字后跟模块名称组成: ```swift import <#module#> ``` -Providing more detail limits which symbols are imported --- -you can specify a specific submodule -or a specific declaration within a module or submodule. -When this detailed form is used, -only the imported symbol -(and not the module that declares it) -is made available in the current scope. +提供更多细节可以限制导入哪些符号——你可以指定特定的子模块或模块或子模块内的特定声明。当使用这种详细形式时,只有被导入的符号(而非声明它的模块)在当前作用域中可用。 ```swift import <#import kind#> <#module#>.<#symbol name#> @@ -96,12 +87,12 @@ import <#module#>.<#submodule#> TODO: Need to add more to this section. --> -> Grammar of an import declaration: +> 导入声明的语法: > -> *import-declaration* → *attributes*_?_ **`import`** *import-kind*_?_ *import-path* +> *导入声明* → *特性*_?_ **`导入`** *导入类型*_?_ *导入路径* > -> *import-kind* → **`typealias`** | **`struct`** | **`class`** | **`enum`** | **`protocol`** | **`let`** | **`var`** | **`func`** \ -> *import-path* → *identifier* | *identifier* **`.`** *import-path* +> *导入类型* → **`类型类型别名`** | **`结构体`** | **`类`** | **`枚举`** | **`协议`** | **`常量`** | **`变量`** | **`函数`** \ +> *导入路径* → *标识符* | *标识符* **`.`** *导入路径* ## Constant Declaration From 7893cfc556bc3b3c5973296d4b37a8fa268eef2e Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:15:06 +0800 Subject: [PATCH 04/67] wip: Constant Declaration --- .../ReferenceManual/Declarations.md | 87 +++++-------------- 1 file changed, 21 insertions(+), 66 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index fb44a2e7..1f989f88 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -35,7 +35,7 @@ Introduce types, operators, variables, and other names and constructs. ## 顶级代码 -Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他命名声明可以被同一模块中每个源文件的代码访问。您可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 [doc:Declarations#Access-Control-Levels](doc:Declarations#Access-Control-Levels)。 +Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他命名声明可以被同一模块中每个源文件的代码访问。您可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 。 有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。 @@ -94,56 +94,23 @@ import <#module#>.<#submodule#> > *导入类型* → **`类型类型别名`** | **`结构体`** | **`类`** | **`枚举`** | **`协议`** | **`常量`** | **`变量`** | **`函数`** \ > *导入路径* → *标识符* | *标识符* **`.`** *导入路径* -## Constant Declaration +## 常量声明 -A *constant declaration* introduces a constant named value into your program. -Constant declarations are declared using the `let` keyword and have the following form: +*常量声明*在您的程序中引入一个名为值的常量。常量声明使用 `let` 关键字声明,具有以下形式: ```swift let <#constant name#>: <#type#> = <#expression#> ``` -A constant declaration defines an immutable binding between the *constant name* -and the value of the initializer *expression*; -after the value of a constant is set, it can't be changed. -That said, if a constant is initialized with a class object, -the object itself can change, -but the binding between the constant name and the object it refers to can't. - -When a constant is declared at global scope, -it must be initialized with a value. -When a constant declaration occurs in the context of a function or method, -it can be initialized later, -as long as it's guaranteed to have a value set -before the first time its value is read. -If the compiler can prove that the constant's value is never read, -the constant isn't required to have a value set at all. -This analysis is called *definite initialization* --- -the compiler proves that a value is definitely set before being read. - -> Note: -> Definite initialization -> can't construct proofs that require domain knowledge, -> and its ability to track state across conditionals has a limit. -> If you can determine that constant always has a value set, -> but the compiler can't prove this is the case, -> try simplifying the code paths that set the value, -> or use a variable declaration instead. - - - -When a constant declaration occurs in the context of a class or structure -declaration, it's considered a *constant property*. -Constant declarations aren't computed properties and therefore don't have getters -or setters. - -If the *constant name* of a constant declaration is a tuple pattern, -the name of each item in the tuple is bound to the corresponding value -in the initializer *expression*. +常量声明定义了*常量名称*与构造器*表达式*的值之间的不可变绑定;一旦常量的值被设置,就无法更改。也就是说,如果常量是用类对象初始化的,对象本身可以改变,但常量名称与它所指向的对象之间的绑定不能改变。 + +当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要在第一次读取其值之前保证已设置值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器证明在读取之前值已被确定设置。 + +> 注意:确定性初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果您可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 + +当常量声明出现在类或结构体声明的上下文中时,它被视为一个*常量属性*。常量声明不是计算属性,因此没有 getter 或 setter。 + +如果常量声明的*常量名称*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中相应的值。 ```swift let (firstNumber, secondNumber) = (10, 42) @@ -157,10 +124,7 @@ let (firstNumber, secondNumber) = (10, 42) ``` --> -In this example, -`firstNumber` is a named constant for the value `10`, -and `secondNumber` is a named constant for the value `42`. -Both constants can now be used independently: +在这个例子中,`firstNumber` 是值 `10` 的命名常量,而 `secondNumber` 是值 `42` 的命名常量。现在这两个常量可以独立使用: ```swift print("The first number is \(firstNumber).") @@ -179,17 +143,9 @@ print("The second number is \(secondNumber).") <- The second number is 42. ``` --> +在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *类型*)是可选的,如中所述。 -The type annotation (`:` *type*) is optional in a constant declaration -when the type of the *constant name* can be inferred, -as described in . - -To declare a constant type property, -mark the declaration with the `static` declaration modifier. -A constant type property of a class is always implicitly final; -you can't mark it with the `class` or `final` declaration modifier -to allow or disallow overriding by subclasses. -Type properties are discussed in . +要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;您不能使用 `class` 或 `final` 声明修饰符来允许或禁止子类重写。类型属性的讨论请参见 -For more information about constants and for guidance about when to use them, -see and . +有关常量的更多信息以及何时使用它们的指导,请参见 。 -> Grammar of a constant declaration: +> 常量声明的语法: > -> *constant-declaration* → *attributes*_?_ *declaration-modifiers*_?_ **`let`** *pattern-initializer-list* +> *常量声明* → *属性*_?_ *声明修饰符*_?_ **`let`** *模式构造器列表* > -> *pattern-initializer-list* → *pattern-initializer* | *pattern-initializer* **`,`** *pattern-initializer-list* \ -> *pattern-initializer* → *pattern* *initializer*_?_ \ -> *initializer* → **`=`** *expression* +> *模式构造器列表* → *模式构造器* | *模式构造器* **`,`** *模式构造器列表* \ +> *模式构造器* → *模式* *构造器*_?_ \ +> *构造器* → **`=`** *表达式* ## Variable Declaration From 13a10e60c06c6e6a2af9cfdfb35ae664379e2f00 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:21:27 +0800 Subject: [PATCH 05/67] wip: Variable Declaration --- .../ReferenceManual/Declarations.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 1f989f88..c63d5aec 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -173,23 +173,15 @@ print("The second number is \(secondNumber).") > *模式构造器* → *模式* *构造器*_?_ \ > *构造器* → **`=`** *表达式* -## Variable Declaration +## 变量声明 -A *variable declaration* introduces a variable named value into your program -and is declared using the `var` keyword. +*变量声明*在您的程序中引入了一个名为值的变量,并使用 `var` 关键字进行声明。 -Variable declarations have several forms that declare different kinds -of named, mutable values, -including stored and computed variables and properties, -stored variable and property observers, and static variable properties. -The appropriate form to use depends on -the scope at which the variable is declared and the kind of variable you intend to declare. +变量声明有几种形式,用于声明不同类型的命名可变值,包括存储变量和计算变量及属性、存储变量和属性观察者,以及静态变量属性。使用的适当形式取决于变量声明的范围和您打算声明的变量类型。 -> Note: You can also declare properties in the context of a protocol declaration, -> as described in . +> 注意:您还可以在协议声明的上下文中声明属性,如 中所述。 -You can override a property in a subclass by marking the subclass's property declaration -with the `override` declaration modifier, as described in . +您可以通过在子类的属性声明中标记 `override` 声明修饰符来重写属性,如 中所述。 ### Stored Variables and Stored Variable Properties From 6b660fe0c337fcd76ff79cfce98bf2cda1dabf2e Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:26:08 +0800 Subject: [PATCH 06/67] wip: Stored Variables and Stored Variable Properties --- .../ReferenceManual/Declarations.md | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index c63d5aec..7de222b2 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -183,36 +183,21 @@ print("The second number is \(secondNumber).") 您可以通过在子类的属性声明中标记 `override` 声明修饰符来重写属性,如 中所述。 -### Stored Variables and Stored Variable Properties +### 存储变量和存储变量属性 -The following form declares a stored variable or stored variable property: +以下形式声明了一个存储变量或存储变量属性: ```swift var <#variable name#>: <#type#> = <#expression#> ``` -You define this form of a variable declaration at global scope, the local scope -of a function, or in the context of a class or structure declaration. -When a variable declaration of this form is declared at global scope or the local -scope of a function, it's referred to as a *stored variable*. -When it's declared in the context of a class or structure declaration, -it's referred to as a *stored variable property*. - -The initializer *expression* can't be present in a protocol declaration, -but in all other contexts, the initializer *expression* is optional. -That said, if no initializer *expression* is present, -the variable declaration must include an explicit type annotation (`:` *type*). - -As with constant declarations, -if a variable declaration omits the initializer *expression*, -the variable must have a value set before the first time it is read. -Also like constant declarations, -if the *variable name* is a tuple pattern, -the name of each item in the tuple is bound to the corresponding value -in the initializer *expression*. - -As their names suggest, the value of a stored variable or a stored variable property -is stored in memory. +您可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种形式的变量声明。当这种形式的变量声明在全局范围或函数的局部范围内声明时,它被称为*存储变量*。当它在类或结构体声明的上下文中声明时,它被称为*存储变量属性*。 + +构造器*表达式*不能出现在协议声明中,但在所有其他上下文中,构造器*表达式*是可选的。也就是说,如果没有构造器*表达式*,变量声明必须包含显式类型注释(`:` *类型*)。 + +与常量声明一样,如果变量声明省略了构造器*表达式*,则在第一次读取该变量之前必须为其设置一个值。同样,像常量声明一样,如果*变量名*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中的相应值。 + +如其名称所示,存储变量或存储变量属性的值存储在内存中。 ### Computed Variables and Computed Properties From f0f1c1fbe445b4d99f4b6c38edf7fdb9fb384772 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:33:56 +0800 Subject: [PATCH 07/67] wip: Computed Variables and Computed Properties --- .../ReferenceManual/Declarations.md | 31 +++++-------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 7de222b2..d4289198 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -199,9 +199,9 @@ var <#variable name#>: <#type#> = <#expression#> 如其名称所示,存储变量或存储变量属性的值存储在内存中。 -### Computed Variables and Computed Properties +### 计算变量和计算属性 -The following form declares a computed variable or computed property: +以下形式声明了一个计算变量或计算属性: ```swift var <#variable name#>: <#type#> { @@ -214,32 +214,15 @@ var <#variable name#>: <#type#> { } ``` -You define this form of a variable declaration at global scope, the local scope -of a function, or in the context of a class, structure, enumeration, or extension declaration. -When a variable declaration of this form is declared at global scope or the local -scope of a function, it's referred to as a *computed variable*. -When it's declared in the context of a class, -structure, or extension declaration, -it's referred to as a *computed property*. +您可以在全局范围、函数的局部范围或类、结构体、枚举或扩展声明的上下文中定义这种形式的变量声明。当这种形式的变量声明在全局范围或函数的局部范围内声明时,它被称为*计算变量*。当它在类、结构体或扩展声明的上下文中声明时,它被称为*计算属性*。 -The getter is used to read the value, -and the setter is used to write the value. -The setter clause is optional, -and when only a getter is needed, you can omit both clauses and simply -return the requested value directly, -as described in . -But if you provide a setter clause, you must also provide a getter clause. +getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter时,可以省略两个子句,直接返回请求的值,如 中所述。但如果提供了 setter 子句,则必须同时提供 getter 子句。 -The *setter name* and enclosing parentheses is optional. -If you provide a setter name, it's used as the name of the parameter to the setter. -If you don't provide a setter name, the default parameter name to the setter is `newValue`, -as described in . +*setter 名称*和括号是可选的。如果您提供了 setter 名称,它将用作 setter 参数的名称。如果您不提供 setter 名称,setter 的默认参数名称是 `newValue`,如 中所述。 -Unlike stored named values and stored variable properties, -the value of a computed named value or a computed property isn't stored in memory. +与存储的命名值和存储的变量属性不同,计算得出的命名值或计算得出的属性的值并不存储在内存中。 -For more information and to see examples of computed properties, -see . +有关更多信息以及查看计算属性的示例,请参见 。 ### Stored Variable Observers and Property Observers From 5dc43a36bc716388b1f9d54dcee5dab2474cffd1 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sat, 24 Aug 2024 22:50:46 +0800 Subject: [PATCH 08/67] wip: Stored Variable Observers and Property Observers --- .../ReferenceManual/Declarations.md | 79 +++++-------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index d4289198..70b0fe90 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -224,39 +224,26 @@ getter 用于读取值,setter 用于写入值。setter 子句是可选的, 有关更多信息以及查看计算属性的示例,请参见 。 -### Stored Variable Observers and Property Observers +### 存储变量观察者和属性观察者 -You can also declare a stored variable or property with `willSet` and `didSet` observers. -A stored variable or property declared with observers has the following form: +您还可以使用 `willSet` 和 `didSet` 观察者声明一个存储变量或属性。带有观察者的存储变量或属性具有以下形式: ```swift var <#variable name#>: <#type#> = <#expression#> { - willSet(<#setter name#>) { - <#statements#> - } - didSet(<#setter name#>) { - <#statements#> - } + willSet(<#setter name#>) { + <#statements#> + } + didSet(<#setter name#>) { + <#statements#> + } } ``` -You define this form of a variable declaration at global scope, the local scope -of a function, or in the context of a class or structure declaration. -When a variable declaration of this form is declared at global scope or the local -scope of a function, the observers are referred to as *stored variable observers*. -When it's declared in the context of a class or structure declaration, -the observers are referred to as *property observers*. +您可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种变量声明形式。当这种形式的变量声明在全局范围或函数的局部范围内声明时,观察者被称为*存储变量观察者*。当它在类或结构声明的上下文中声明时,观察者被称为*属性观察者*。 -You can add property observers to any stored property. You can also add property -observers to any inherited property (whether stored or computed) by overriding -the property within a subclass, as described in . +您可以为任何存储属性添加属性观察者。您还可以通过在子类中重写属性,为任何继承属性(无论是存储的还是计算的)添加属性观察者,如 中所述。 -The initializer *expression* is optional in the context of a class or structure declaration, -but required elsewhere. The *type* annotation is optional -when the type can be inferred from the initializer *expression*. -This expression is evaluated the first time you read the property's value. -If you overwrite the property's initial value without reading it, -this expression is evaluated before the first time you write to the property. +构造器*表达式*在类或结构体声明的上下文中是可选的,但在其他地方是必需的。当类型可以从构造器*表达式*中推断时,*类型*标注是可选的。该表达式在您第一次读取属性值时被评估。如果您在读取属性之前覆盖了属性的初始值,则在第一次写入属性之前会评估该表达式。 -The `willSet` and `didSet` observers provide a way to observe (and to respond appropriately) -when the value of a variable or property is being set. -The observers aren't called when the variable or property -is first initialized. -Instead, they're called only when the value is set outside of an initialization context. - -A `willSet` observer is called just before the value of the variable or property -is set. The new value is passed to the `willSet` observer as a constant, -and therefore it can't be changed in the implementation of the `willSet` clause. -The `didSet` observer is called immediately after the new value is set. In contrast -to the `willSet` observer, the old value of the variable or property -is passed to the `didSet` observer in case you still need access to it. That said, -if you assign a value to a variable or property within its own `didSet` observer clause, -that new value that you assign will replace the one that was just set and passed to -the `willSet` observer. - -The *setter name* and enclosing parentheses in the `willSet` and `didSet` clauses are optional. -If you provide setter names, -they're used as the parameter names to the `willSet` and `didSet` observers. -If you don't provide setter names, -the default parameter name to the `willSet` observer is `newValue` -and the default parameter name to the `didSet` observer is `oldValue`. - -The `didSet` clause is optional when you provide a `willSet` clause. -Likewise, the `willSet` clause is optional when you provide a `didSet` clause. - -If the body of the `didSet` observer refers to the old value, -the getter is called before the observer, -to make the old value available. -Otherwise, the new value is stored without calling the superclass's getter. -The example below shows a computed property that's defined by the superclass -and overridden by its subclasses to add an observer. +`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外设置值时被调用。 + +`willSet` 观察者在变量或属性的值被设置之前被调用。新值作为常量传递给 `willSet` 观察者,因此在 `willSet` 子句的实现中无法更改。`didSet` 观察者在新值被设置后立即被调用。与 `willSet` 观察者不同,变量或属性的旧值会传递给 `didSet` 观察者,以防你仍然需要访问它。也就是说,如果你在其自己的 `didSet` 观察者子句中给变量或属性赋值,那么你赋的这个新值将替代刚刚设置并传递给 `willSet` 观察者的值。 + +*setter 名称*和 `willSet` 与 `didSet` 子句中的括号是可选的。如果提供了 setter 名称,它们将作为 `willSet` 和 `didSet` 观察者的参数名称。如果不提供 setter 名称,`willSet` 观察者的默认参数名称是 `newValue`,而 `didSet` 观察者的默认参数名称是 `oldValue`。 + +`didSet` 子句在提供 `willSet` 子句时是可选的。同样,在提供 `didSet` 子句时,`willSet` 子句也是可选的。 + +如果 `didSet` 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用。否则,新的值会被存储,而不调用超类的 getter。下面的示例显示了一个由超类定义并被其子类重写以添加观察者的计算属性。 ```swift class Superclass { @@ -389,9 +353,8 @@ newAndOld.x = 200 ``` --> -For more information and to see an example of how to use property observers, -see . +有关更多信息以及如何使用属性观察者的示例,请参见 -### Type Variable Properties +### 类型变量属性 -To declare a type variable property, -mark the declaration with the `static` declaration modifier. -Classes can mark type computed properties with the `class` declaration modifier instead -to allow subclasses to override the superclass’s implementation. -Type properties are discussed in . +要声明一个类型变量属性,请使用 `static` 声明修饰符标记声明。类可以使用 `class` 声明修饰符标记类型计算属性,以允许子类覆盖超类的实现。类型属性的讨论请参见 。 -> Grammar of a variable declaration: +> 变量声明的语法: > -> *variable-declaration* → *variable-declaration-head* *pattern-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* *initializer* *willSet-didSet-block* \ -> *variable-declaration* → *variable-declaration-head* *variable-name* *type-annotation* *initializer*_?_ *willSet-didSet-block* +> *变量-声明* → *变量-声明-头* *模式-初始化-列表* \ +> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *代码-块* \ +> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *getter-setter-块* \ +> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *getter-setter-关键字-块* \ +> *变量-声明* → *变量-声明-头* *变量-名* *构造器* *willSet-didSet-块* \ +> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *构造器*_?_ *willSet-didSet-块* > -> *variable-declaration-head* → *attributes*_?_ *declaration-modifiers*_?_ **`var`** \ -> *variable-name* → *identifier* +> *变量-声明-头* → *属性*_?_ *声明-修饰符*_?_ **`var`** \ +> *变量-名* → *标识符* > -> *getter-setter-block* → *code-block* \ -> *getter-setter-block* → **`{`** *getter-clause* *setter-clause*_?_ **`}`** \ -> *getter-setter-block* → **`{`** *setter-clause* *getter-clause* **`}`** \ -> *getter-clause* → *attributes*_?_ *mutation-modifier*_?_ **`get`** *code-block* \ -> *setter-clause* → *attributes*_?_ *mutation-modifier*_?_ **`set`** *setter-name*_?_ *code-block* \ -> *setter-name* → **`(`** *identifier* **`)`** +> *getter-setter-块* → *代码块* \ +> *getter-setter-块* → **`{`** *getter-子句* *setter-子句*_?_ **`}`** \ +> *getter-setter-块* → **`{`** *setter-子句* *getter-子句* **`}`** \ +> *getter-子句* → *特性*_?_ *可变-修饰符*_?_ **`get`** *代码-块* \ +> *setter-子句* → *特性*_?_ *可变-修饰符*_?_ **`set`** *setter-名称*_?_ *代码-块* \ +> *setter-名称* → **`(`** *标识符* **`)`** > -> *getter-setter-keyword-block* → **`{`** *getter-keyword-clause* *setter-keyword-clause*_?_ **`}`** \ -> *getter-setter-keyword-block* → **`{`** *setter-keyword-clause* *getter-keyword-clause* **`}`** \ -> *getter-keyword-clause* → *attributes*_?_ *mutation-modifier*_?_ **`get`** \ -> *setter-keyword-clause* → *attributes*_?_ *mutation-modifier*_?_ **`set`** +> *getter-setter-关键字-块* → **`{`** *getter-关键字-子句* *setter-关键字-子句*_?_ **`}`** \ +> *getter-setter-关键字-块* → **`{`** *setter-关键字-子句* *getter-关键字-子句* **`}`** \ +> *getter-关键字-子句* → *属性*_?_ *可变-修饰符*_?_ **`get`** \ +> *setter-关键字-子句* → *属性*_?_ *可变-修饰符*_?_ **`set`** > -> *willSet-didSet-block* → **`{`** *willSet-clause* *didSet-clause*_?_ **`}`** \ -> *willSet-didSet-block* → **`{`** *didSet-clause* *willSet-clause*_?_ **`}`** \ -> *willSet-clause* → *attributes*_?_ **`willSet`** *setter-name*_?_ *code-block* \ -> *didSet-clause* → *attributes*_?_ **`didSet`** *setter-name*_?_ *code-block* +> *willSet-didSet-block* → **`{`** *willSet-子句* *didSet-子句*_?_ **`}`** \ +> *willSet-didSet-block* → **`{`** *didSet-子句* *willSet-子句*_?_ **`}`** \ +> *willSet-子句* → *特性*_?_ **`willSet`** *setter-名称*_?_ *代码-块* \ +> *didSet-子句* → *特性*_?_ **`didSet`** *setter-名称*_?_ *代码-块* -## Type Alias Declaration +## 类型别名声明 -A *type alias declaration* introduces a named alias of an existing type into your program. -Type alias declarations are declared using the `typealias` keyword and have the following form: +*类型别名声明*将现有类型的命名别名引入到您的程序中。类型别名声明使用 `typealias` 关键字声明,具有以下形式: ```swift typealias <#name#> = <#existing type#> ``` -After a type alias is declared, the aliased *name* can be used -instead of the *existing type* everywhere in your program. -The *existing type* can be a named type or a compound type. -Type aliases don't create new types; -they simply allow a name to refer to an existing type. +在声明类型别名后,别名*名称*可以在程序中的任何地方替代*现有类型*使用。*现有类型*可以是命名类型或复合类型。类型别名不会创建新类型;它们只是允许一个名称引用现有类型。 -A type alias declaration can use generic parameters -to give a name to an existing generic type. The type alias -can provide concrete types for some or all of the generic parameters -of the existing type. -For example: +A type alias declaration can use generic parameters to give a name to an existing generic type. The type alias can provide concrete types for some or all of the generic parameters of the existing type. For example: +类型别名声明可以使用泛型参数为现有的泛型类型命名。类型别名可以为现有类型的某些或所有泛型参数提供具体类型。例如: ```swift typealias StringDictionary = Dictionary @@ -451,9 +443,7 @@ var dictionary2: Dictionary = [:] ``` --> -When a type alias is declared with generic parameters, the constraints on those -parameters must match exactly the constraints on the existing type's generic parameters. -For example: +当声明一个带有泛型参数的类型别名时,这些参数的约束必须与现有类型的泛型参数的约束完全匹配。例如: ```swift typealias DictionaryOfInts = Dictionary @@ -467,14 +457,9 @@ typealias DictionaryOfInts = Dictionary ``` --> -Because the type alias and the existing type can be used interchangeably, -the type alias can't introduce additional generic constraints. +因为类型别名和现有类型可以互换使用,类型别名不能引入额外的泛型约束。 -A type alias can forward an existing type's generic parameters -by omitting all generic parameters from the declaration. -For example, -the `Diccionario` type alias declared here -has the same generic parameters and constraints as `Dictionary`. +类型别名可以通过省略声明中的所有泛型参数来转发现有类型的泛型参数。例如,这里声明的 `Diccionario` 类型别名具有与 `Dictionary` 相同的泛型参数和约束。 ```swift typealias Diccionario = Dictionary @@ -500,11 +485,7 @@ typealias Diccionario = Dictionary typealias NotProvidingTheCorrectConstraints = Dictionary typealias ProvidingMoreSpecificConstraints = Dictionary --> - -Inside a protocol declaration, -a type alias can give a shorter and more convenient name -to a type that's used frequently. -For example: +在协议声明中,类型别名可以为经常使用的类型提供一个更短和更方便的名称。例如: ```swift protocol Sequence { @@ -533,17 +514,15 @@ func sum(_ sequence: T) -> Int where T.Element == Int { ``` --> -Without this type alias, -the `sum` function would have to refer to the associated type -as `T.Iterator.Element` instead of `T.Element`. +没有这种类型别名,`sum` 函数必须将关联类型称为 `T.Iterator.Element`,而不是 `T.Element`。 -See also . +另见 。 -> Grammar of a type alias declaration: +> 类型别名声明的语法: > -> *typealias-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`typealias`** *typealias-name* *generic-parameter-clause*_?_ *typealias-assignment* \ -> *typealias-name* → *identifier* \ -> *typealias-assignment* → **`=`** *type* +> *类型别名-声明* → *属性*_?_ *访问-级别-修饰符*_?_ **`typealias`** *typealias-名称* *泛型-参数-子句*_?_ *typealias-赋值* \ +> *typealias-名称* → *标识符* \ +> *typealias-赋值* → **`=`** *类型* + 当常量声明出现在类或结构体声明的上下文中时,它被视为一个*常量属性*。常量声明不是计算属性,因此没有 getter 或 setter。 如果常量声明的*常量名称*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中相应的值。 @@ -353,7 +359,6 @@ newAndOld.x = 200 ``` --> - 有关更多信息以及如何使用属性观察者的示例,请参见 -## Function Declaration +## 函数声明 -A *function declaration* introduces a function or method into your program. -A function declared in the context of class, structure, enumeration, or protocol -is referred to as a *method*. -Function declarations are declared using the `func` keyword and have the following form: +*函数声明*将一个函数或方法引入到你的程序中。在类、结构体、枚举或协议的上下文中声明的函数被称为*方法*。函数声明使用 `func` 关键字声明,具有以下形式: ```swift func <#function name#>(<#parameters#>) -> <#return type#> { - <#statements#> + <#statements#> } ``` -If the function has a return type of `Void`, -the return type can be omitted as follows: +如果函数的返回类型是 `Void` ,则可以省略返回类型,如下所示: ```swift func <#function name#>(<#parameters#>) { - <#statements#> + <#statements#> } ``` -The type of each parameter must be included --- -it can't be inferred. -If you write `inout` in front of a parameter's type, -the parameter can be modified inside the scope of the function. -In-out parameters are discussed in detail -in , below. -A function declaration whose *statements* -include only a single expression -is understood to return the value of that expression. -This implicit return syntax is considered -only when the expression's type and the function's return type -aren't `Void` -and aren't an enumeration like `Never` that doesn't have any cases. +每个参数的类型必须明确指定,而不能被推断出来。如果在参数类型前写上 `inout`,则该参数可以在函数的作用域内被修改。关于输入输出参数的详细讨论请参见下面的 。 + +如果一个函数声明中的*语句*只包含一个表达式,则默认返回该表达式的值。只有在表达式的类型和函数的返回类型不是 `Void`,并且不是像 `Never` 那样没有任何情况的枚举时,才会考虑这种隐式返回语法。 -Functions can return multiple values using a tuple type -as the return type of the function. +函数可以使用元组类型作为返回类型来返回多个值。 -A function definition can appear inside another function declaration. -This kind of function is known as a *nested function*. - -A nested function is nonescaping if it captures -a value that's guaranteed to never escape --- -such as an in-out parameter --- -or passed as a nonescaping function argument. -Otherwise, the nested function is an escaping function. +一个函数定义可以出现在另一个函数声明内部。这种函数被称为*嵌套函数*。 -For a discussion of nested functions, -see . +如果一个嵌套函数捕获了一个保证不会逃逸的值——例如一个 in-out 参数——或者作为一个非逃逸函数参数传递,那么这个嵌套函数就是非逃逸的。否则,嵌套函数就是逃逸的。 ### Parameter Names +有关嵌套函数的讨论,请参见 。 Function parameters are a comma-separated list where each parameter has one of several forms. From 35b9374cbdcda3a089da3154f4d2df9a0e4d8b2b Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sun, 25 Aug 2024 13:37:04 +0800 Subject: [PATCH 12/67] wip: Parameter Names --- .../ReferenceManual/Declarations.md | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 8fe8aab4..2114c259 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -576,26 +576,17 @@ func <#function name#>(<#parameters#>) { 如果一个嵌套函数捕获了一个保证不会逃逸的值——例如一个 in-out 参数——或者作为一个非逃逸函数参数传递,那么这个嵌套函数就是非逃逸的。否则,嵌套函数就是逃逸的。 -### Parameter Names 有关嵌套函数的讨论,请参见 。 -Function parameters are a comma-separated list -where each parameter has one of several forms. -The order of arguments in a function call -must match the order of parameters in the function's declaration. -The simplest entry in a parameter list has the following form: +### 参数名称 + +函数参数是一个以逗号分隔的列表,其中每个参数都有几种形式之一。在函数调用中,参数的顺序必须与函数声明中的参数顺序匹配。参数列表中最简单的项具有以下形式: ```swift <#parameter name#>: <#parameter type#> ``` -A parameter has a name, -which is used within the function body, -as well as an argument label, -which is used when calling the function or method. -By default, -parameter names are also used as argument labels. -For example: +一个参数有一个名称,在函数体内使用,以及一个实参标签,在调用函数或方法时使用。默认情况下,参数名称也用作实参标签。例如: ```swift func f(x: Int, y: Int) -> Int { return x + y } @@ -618,23 +609,17 @@ f(x: 1, y: 2) // both x and y are labeled Tracking bug is --> -You can override the default behavior for argument labels -with one of the following forms: +您可以使用以下形式之一覆盖参数标签的默认行为: ```swift <#argument label#> <#parameter name#>: <#parameter type#> _ <#parameter name#>: <#parameter type#> ``` -A name before the parameter name -gives the parameter an explicit argument label, -which can be different from the parameter name. -The corresponding argument must use the given argument label -in function or method calls. -An underscore (`_`) before a parameter name -suppresses the argument label. -The corresponding argument must have no label in function or method calls. +在参数名称之前添加一个名称为参数提供了一个显式的实参标签,该标签可以与参数名称不同。相应的参数在函数或方法调用中必须使用给定的实参标签。 + +在参数名称前加下划线(`_`)可以抑制参数标签。相应的参数在函数或方法调用中必须没有标签。 ```swift func repeatGreeting(_ greeting: String, count n: Int) { /* Greet n times */ } From 5f76bcc01a6ed3c445894cb8196d9018858ef908 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sun, 25 Aug 2024 13:41:16 +0800 Subject: [PATCH 13/67] wip: Parameter Modifiers --- swift-6-beta.docc/ReferenceManual/Declarations.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2114c259..41d3ce2e 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -635,17 +635,15 @@ repeatGreeting("Hello, world!", count: 2) // count is labeled, greeting is not ``` --> -### Parameter Modifiers +### 参数修饰符 -A *parameter modifier* changes how an argument is passed to the function. +*参数修饰符*改变了参数传递给函数的方式。 ```swift <#argument label#> <#parameter name#>: <#parameter modifier#> <#parameter type#> ``` -To use a parameter modifier, -write `inout`, `borrowing`, or `consuming` -before the argument's type. +要使用参数修饰符,请在参数类型之前写 `inout`、`borrowing` 或 `consuming`。 ```swift func someFunction(a: inout A, b: consuming B, c: C) { ... } From 8c76d50fa5a6ffabc57d7ce5b7ab1b1716ce13e4 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Sun, 25 Aug 2024 13:58:20 +0800 Subject: [PATCH 14/67] wip: In-Out Parameters --- .../ReferenceManual/Declarations.md | 75 +++++-------------- 1 file changed, 19 insertions(+), 56 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 41d3ce2e..3260f326 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -649,13 +649,9 @@ repeatGreeting("Hello, world!", count: 2) // count is labeled, greeting is not func someFunction(a: inout A, b: consuming B, c: C) { ... } ``` -#### In-Out Parameters - -By default, function arguments in Swift are passed by value: -Any changes made within the function are not visible in the caller. -To make an in-out parameter instead, -you apply the `inout` parameter modifier. +#### 输入输出参数 +默认情况下,Swift 中的函数参数是按值传递的:在函数内部所做的任何更改在调用者中不可见。要改为使用输入输出参数,您需要应用 `inout` 参数修饰符。 ```swift func someFunction(a: inout Int) { @@ -663,9 +659,8 @@ func someFunction(a: inout Int) { } ``` -When calling a function that includes in-out parameters, -the in-out argument must be prefixed with an ampersand (`&`) -to mark that the function call can change the argument's value. + +在调用包含输入输出参数的函数时,输入输出参数必须以一个和号 (`&`) 开头,以标记该函数调用可以改变参数的值。 ```swift var x = 7 @@ -673,38 +668,17 @@ someFunction(&x) print(x) // Prints "8" ``` -In-out parameters are passed as follows: +输入输出参数的传递方式如下: -1. When the function is called, - the value of the argument is copied. -2. In the body of the function, - the copy is modified. -3. When the function returns, - the copy's value is assigned to the original argument. +1. 当函数被调用时,参数的值会被复制。 +2. 在函数体内,副本被修改。 +3. 当函数返回时,副本的值被赋给原始参数。 -This behavior is known as *copy-in copy-out* -or *call by value result*. -For example, -when a computed property or a property with observers -is passed as an in-out parameter, -its getter is called as part of the function call -and its setter is called as part of the function return. - -As an optimization, -when the argument is a value stored at a physical address in memory, -the same memory location is used both inside and outside the function body. -The optimized behavior is known as *call by reference*; -it satisfies all of the requirements -of the copy-in copy-out model -while removing the overhead of copying. -Write your code using the model given by copy-in copy-out, -without depending on the call-by-reference optimization, -so that it behaves correctly with or without the optimization. - -Within a function, don't access a value that was passed as an in-out argument, -even if the original value is available in the current scope. -Accessing the original is a simultaneous access of the value, -which violates memory exclusivity. +这种行为被称为 *copy-in copy-out* 或 *值传递*。例如,当一个计算属性或一个带观察者的属性作为输入输出参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。 + +作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。优化后的行为被称为 *引用传递*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。 + +在函数内,不要访问作为 in-out 参数传递的值,即使原始值在当前作用域中可用。访问原始值是对该值的同时访问,这违反了内存独占性。 ```swift var someValue: Int @@ -716,8 +690,7 @@ func someFunction(a: inout Int) { someFunction(&someValue) ``` -For the same reason, -you can't pass the same value to multiple in-out parameters. +出于同样的原因,您不能将相同的值传递给多个输入输出参数。 ```swift var someValue: Int @@ -730,9 +703,7 @@ func someFunction(a: inout Int, b: inout Int) { someFunction(&someValue, &someValue) ``` -For more information about memory safety and memory exclusivity, -see . - +有关内存安全和内存独占的更多信息,请参见 -A closure or nested function -that captures an in-out parameter must be nonescaping. -If you need to capture an in-out parameter -without mutating it, -use a capture list to explicitly capture the parameter immutably. +A closure or nested function that captures an in-out parameter must be nonescaping. If you need to capture an in-out parameter without mutating it, use a capture list to explicitly capture the parameter immutably. +一个捕获输入输出参数的闭包或嵌套函数必须是非逃逸的。如果您需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 ```swift func someFunction(a: inout Int) -> () -> Int { @@ -770,11 +738,7 @@ func someFunction(a: inout Int) -> () -> Int { ``` --> -If you need to capture and mutate an in-out parameter, -use an explicit local copy, -such as in multithreaded code that ensures -all mutation has finished before the function returns. - +如果您需要捕获并修改一个 in-out 参数,请使用一个显式的局部副本,例如在多线程代码中,确保所有修改在函数返回之前都已完成。 ```swift func multithreadedFunction(queue: DispatchQueue, x: inout Int) { // Make a local copy and manually copy it back. @@ -805,8 +769,7 @@ func multithreadedFunction(queue: DispatchQueue, x: inout Int) { ``` --> -For more discussion and examples of in-out parameters, -see . +有关输入输出参数的更多讨论和示例,请参见 -#### Borrowing and Consuming Parameters +#### 借用和消耗参数 -By default, Swift uses a set of rules -to automatically manage object lifetime across function calls, -copying values when required. -The default rules are designed to minimize overhead in most cases --- -if you want more specific control, -you can apply the `borrowing` or `consuming` parameter modifier. -In this case, -use `copy` to explicitly mark copy operations. +默认情况下,Swift 使用一套规则在函数调用之间自动管理对象生命周期,在需要时复制值。默认规则旨在在大多数情况下最小化开销——如果您想要更具体的控制,可以应用 `borrowing` 或 `consuming` 参数修饰符。在这种情况下,使用 `copy` 显式标记复制操作。 -Regardless of whether you use the default rules, -Swift guarantees that object lifetime and -ownership are correctly managed in all cases. -These parameter modifiers impact only the relative efficiency -of particular usage patterns, not correctness. +无论您是否使用默认规则,Swift 确保在所有情况下对象的生命周期和所有权都得到正确管理。这些参数修饰符仅影响特定使用模式的相对效率,而不影响正确性。 -The `borrowing` modifier indicates that the function -does not keep the parameter's value. -In this case, the caller maintains ownership of the object -and the responsibility for the object's lifetime. -Using `borrowing` minimizes overhead when the function -uses the object only transiently. +`borrowing` 修饰符表示该函数不保留参数的值。在这种情况下,调用者保持对象的所有权,并对对象的生命周期负责。使用 `borrowing` 可以在函数仅暂时使用对象时最小化开销。 ```swift // `isLessThan` does not keep either argument @@ -843,9 +827,7 @@ func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { } ``` -If the function needs to keep the parameter's value -for example, by storing it in a global variable --- -you use `copy` to explicitly copy that value. +如果函数需要保持参数的值,例如,通过将其存储在全局变量中 --- 您可以使用 `copy` 明确地复制该值。 ```swift // As above, but this `isLessThan` also wants to record the smallest value @@ -859,11 +841,7 @@ func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { } ``` -Conversely, -the `consuming` parameter modifier indicates -that the function takes ownership of the value, -accepting responsibility for either storing or destroying it -before the function returns. +相反,`consuming` 参数修饰符表示该函数拥有该值的所有权,负责在函数返回之前存储或销毁它。 ```swift // `store` keeps its argument, so mark it `consuming` @@ -872,17 +850,14 @@ func store(a: consuming A) { } ``` -Using `consuming` minimizes overhead when the caller no longer -needs to use the object after the function call. +使用 `consuming` 可以在调用者在函数调用后不再需要使用该对象时,最小化开销。 ```swift // Usually, this is the last thing you do with a value store(a: value) ``` -If you keep using a copyable object after the function call, -the compiler automatically makes a copy of that object -before the function call. +如果在函数调用后继续使用可复制对象,编译器会在函数调用之前自动复制该对象。 ```swift // The compiler inserts an implicit copy here @@ -890,9 +865,7 @@ store(a: someValue) // This function consumes someValue print(someValue) // This uses the copy of someValue ``` -Unlike `inout`, neither `borrowing` nor -`consuming` parameters require any special -notation when you call the function: +与 `inout` 不同,`borrowing` 和 `consuming` 参数在调用函数时不需要任何特殊标记: ```swift func someFunction(a: borrowing A, b: consuming B) { ... } @@ -900,14 +873,7 @@ func someFunction(a: borrowing A, b: consuming B) { ... } someFunction(a: someA, b: someB) ``` -The explicit use of either `borrowing` or `consuming` -indicates your intention to more tightly control -the overhead of runtime ownership management. -Because copies can cause unexpected runtime ownership -operations, -parameters marked with either of these -modifiers cannot be copied unless you -use an explicit `copy` keyword: +明确使用 `borrowing` 或 `consuming` 表示您希望更严格地控制运行时所有权管理的开销。因为复制可能导致意外的运行时所有权操作,所以标记为这两种修饰符的参数在没有使用显式的 `copy` 关键字的情况下不能被复制: ```swift func borrowingFunction1(a: borrowing A) { From 785b2100f72e2ce6b7ccdc3ab4b1680542dd5319 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 26 Aug 2024 12:50:22 +0800 Subject: [PATCH 16/67] wip: Special Kinds of Parameters --- .../ReferenceManual/Declarations.md | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2f207ee7..14072bdc 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -915,12 +915,9 @@ func consumingFunction3(a: consuming A) { TODO: Any change of parameter modifier is ABI-breaking --> -### Special Kinds of Parameters +### 特殊类型的参数 -Parameters can be ignored, -take a variable number of values, -and provide default values -using the following forms: +参数可以被忽略,接受可变数量的值,并使用以下形式提供默认值: ```swift _ : <#parameter type#> @@ -928,24 +925,11 @@ _ : <#parameter type#> <#parameter name#>: <#parameter type#> = <#default argument value#> ``` -An underscore (`_`) parameter -is explicitly ignored and can't be accessed within the body of the function. - -A parameter with a base type name followed immediately by three dots (`...`) -is understood as a variadic parameter. -A parameter that immediately follows a variadic parameter -must have an argument label. -A function can have multiple variadic parameters. -A variadic parameter is treated as an array that contains elements of the base type name. -For example, the variadic parameter `Int...` is treated as `[Int]`. -For an example that uses a variadic parameter, -see . - -A parameter with an equal sign (`=`) and an expression after its type -is understood to have a default value of the given expression. -The given expression is evaluated when the function is called. -If the parameter is omitted when calling the function, -the default value is used instead. +下划线 (`_`) 参数被明确忽略,无法在函数体内访问。 + +带有基本类型名称后面紧跟三个点(`...`)的参数被理解为可变参数。紧跟在可变参数后面的参数必须有一个参数标签。一个函数可以有多个可变参数。可变参数被视为包含基本类型名称元素的数组。例如,可变参数 `Int...` 被视为 `[Int]`。有关使用可变参数的示例,请参见 。 + +一个带有等号 (`=`) 的参数及其类型后面的表达式被理解为具有给定表达式的默认值。给定的表达式在调用函数时被评估。如果在调用函数时省略了该参数,则使用默认值。 ```swift func f(x: Int = 42) -> Int { return x } From 5277d252cd0e0e763dc082bcbb0d08e8317803ab Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 26 Aug 2024 12:55:36 +0800 Subject: [PATCH 17/67] wip: Special Kinds of Methods --- .../ReferenceManual/Declarations.md | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 14072bdc..0fed7e5e 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -981,24 +981,13 @@ f(7) // Invalid, missing argument label ``` --> -### Special Kinds of Methods - -Methods on an enumeration or a structure -that modify `self` must be marked with the `mutating` declaration modifier. - -Methods that override a superclass method -must be marked with the `override` declaration modifier. -It's a compile-time error to override a method without the `override` modifier -or to use the `override` modifier on a method -that doesn't override a superclass method. - -Methods associated with a type -rather than an instance of a type -must be marked with the `static` declaration modifier for enumerations and structures, -or with either the `static` or `class` declaration modifier for classes. -A class type method marked with the `class` declaration modifier -can be overridden by a subclass implementation; -a class type method marked with `class final` or `static` can't be overridden. +### 特殊类型的方法 + +对枚举或结构体的方法,如果修改了 `self`,必须标记为 `mutating` 声明修饰符。 + +重写超类方法的方法必须标记为 `override` 声明修饰符。没有 `override` 修饰符而重写方法,或者在不重写超类方法的情况下使用 `override` 修饰符,都是编译时错误。 + +与类型相关的方法,而不是与类型实例相关的方法,必须使用 static 声明修饰符来标记(枚举和结构体使用 static,类可以使用 static 或 class 声明修饰符)。用 class 声明修饰符标记的类类型方法可以被子类的实现重写;用 class final 或 static 标记的类类型方法则不能被重写。 -### Methods with Special Names - -Several methods that have special names -enable syntactic sugar for function call syntax. -If a type defines one of these methods, -instances of the type can be used in function call syntax. -The function call is understood to be a call to -one of the specially named methods on that instance. - -A class, structure, or enumeration type -can support function call syntax -by defining a `dynamicallyCall(withArguments:)` method -or a `dynamicallyCall(withKeywordArguments:)` method, -as described in , -or by defining a call-as-function method, as described below. -If the type defines -both a call-as-function method -and one of the methods used by the `dynamicCallable` attribute, -the compiler gives preference to the call-as-function method -in circumstances where either method could be used. - -The name of a call-as-function method is `callAsFunction()`, -or another name that begins with `callAsFunction(` -and adds labeled or unlabeled arguments --- -for example, `callAsFunction(_:_:)` and `callAsFunction(something:)` -are also valid call-as-function method names. +### 特殊名称的方法 + +几种具有特殊名称的方法使函数调用语法变得更加简洁。如果一个类型定义了这些方法之一,该类型的实例可以在函数调用语法中使用。函数调用被理解为对该实例上某个特殊命名方法的调用。 + +类、结构体或枚举类型可以通过定义一个 `dynamicallyCall(withArguments:)` 方法或一个 `dynamicallyCall(withKeywordArguments:)` 方法来支持函数调用语法,如 中所述,或者通过定义一个 call-as-function 的方法,如下所述。如果该类型同时定义了一个作为函数调用的方法和 `dynamicCallable` 特性使用的其中一个方法,则在可以使用任一方法的情况下,编译器优先选择 call-as-function 的方法。 + +call-as-function 的方法的名称是 `callAsFunction()`,或者另一个以 `callAsFunction(` 开头并添加带标签或不带标签的参数的名称——例如, `callAsFunction(_:_:)` 和 `callAsFunction(something:)` 也是有效的调用作为函数的方法名称。 -The following function calls are equivalent: +以下函数调用是等效的: ```swift struct CallableStruct { @@ -1091,22 +1072,9 @@ callable.callAsFunction(4, scale: 2) ``` --> -The call-as-function methods -and the methods from the `dynamicCallable` attribute -make different trade-offs between -how much information you encode into the type system -and how much dynamic behavior is possible at runtime. -When you declare a call-as-function method, -you specify the number of arguments, -and each argument's type and label. -The `dynamicCallable` attribute's methods specify only the type -used to hold the array of arguments. - -Defining a call-as-function method, -or a method from the `dynamicCallable` attribute, -doesn't let you use an instance of that type -as if it were a function in any context other than a function call expression. -For example: +call-as-function 的方法和来自 `dynamicCallable` 特性的方法在将多少信息编码到类型系统与在运行时可能的动态行为之间做出了不同的权衡。当您声明一个 call-as-function 的方法时,您需要指定参数的数量,以及每个参数的类型和标签。`dynamicCallable` 特性的方法仅指定用于保存参数数组的类型。 + +定义一个 call-as-function,或者来自 `dynamicCallable` 特性的方法,并不允许你在函数调用表达式以外的任何上下文中将该类型的实例用作函数。例如: ```swift let someFunction1: (Int, Int) -> Void = callable(_:scale:) // Error @@ -1132,69 +1100,38 @@ let someFunction2: (Int, Int) -> Void = callable.callAsFunction(_:scale:) ``` --> -The `subscript(dynamicMember:)` subscript -enables syntactic sugar for member lookup, -as described in . +`subscript(dynamicMember:)` 下标为成员查找提供了语法糖,如 中所述。 ### Throwing Functions and Methods +抛出函数和方法 -Functions and methods that can throw an error must be marked with the `throws` keyword. -These functions and methods are known as *throwing functions* -and *throwing methods*. -They have the following form: - -```swift -func <#function name#>(<#parameters#>) throws -> <#return type#> { - <#statements#> -} -``` +Functions and methods that can throw an error must be marked with the `throws` keyword. These functions and methods are known as *throwing functions* and *throwing methods*. They have the following form: +可以抛出错误的函数和方法必须标记为 `throws` 关键字。这些函数和方法被称为 *抛出函数* 和 *抛出方法*。它们具有以下形式: -A function that throws a specific error type has the following form: - -```swift -func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> { - <#statements#> -} -``` + func <#function name#>(<#parameters#>) throws -> <#return type#> { + <#statements#> + } -Calls to a throwing function or method must be wrapped in a `try` or `try!` expression -(that is, in the scope of a `try` or `try!` operator). -A function's type includes whether it can throw an error -and what type of error it throws. -This subtype relationship means, for example, you can use a nonthrowing function -in a context where a throwing one is expected. -For more information about the type of a throwing function, -see . -For examples of working with errors that have explicit types, -see . +A function that throws a specific error type has the following form: +抛出特定错误类型的函数具有以下形式: -You can't overload a function based only on whether the function can throw an error. -That said, -you can overload a function based on whether a function *parameter* can throw an error. + func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> { + <#statements#> + } -A throwing method can't override a nonthrowing method, -and a throwing method can't satisfy a protocol requirement for a nonthrowing method. -That said, a nonthrowing method can override a throwing method, -and a nonthrowing method can satisfy a protocol requirement for a throwing method. -### Rethrowing Functions and Methods +Calls to a throwing function or method must be wrapped in a `try` or `try!` expression (that is, in the scope of a `try` or `try!` operator). +调用抛出函数或方法的必须被包裹在一个 `try` 或 `try!` 表达式中(即,在 `try` 或 `try!` 操作符的作用域内)。 -A function or method can be declared with the `rethrows` keyword -to indicate that it throws an error only if one of its function parameters throws an error. -These functions and methods are known as *rethrowing functions* -and *rethrowing methods*. -Rethrowing functions and methods -must have at least one throwing function parameter. +A function's type includes whether it can throw an error and what type of error it throws. This subtype relationship means, for example, you can use a nonthrowing function in a context where a throwing one is expected. For more information about the type of a throwing function, see [doc:Types#Function-Type](doc:Types#Function-Type). For examples of working with errors that have explicit types, see [doc:ErrorHandling#Specifying-the-Error-Type](doc:ErrorHandling#Specifying-the-Error-Type). +一个函数的类型包括它是否可以抛出错误以及它抛出什么类型的错误。这种子类型关系意味着,例如,您可以在期望抛出错误的上下文中使用一个不抛出错误的函数。有关抛出函数类型的更多信息,请参见 [doc:Types#Function-Type](doc:Types#Function-Type)。有关处理具有显式类型的错误的示例,请参见 [doc:ErrorHandling#Specifying-the-Error-Type](doc:ErrorHandling#Specifying-the-Error-Type)。 -```swift -func someFunction(callback: () throws -> Void) rethrows { - try callback() -} -``` +You can't overload a function based only on whether the function can throw an error. That said, you can overload a function based on whether a function *parameter* can throw an error. +您不能仅仅根据函数是否可以抛出错误来重载函数。也就是说,您可以根据函数的 *参数* 是否可以抛出错误来重载函数。 - -A rethrowing function or method can contain a `throw` statement -only inside a `catch` clause. -This lets you call the throwing function inside a `do`-`catch` statement -and handle errors in the `catch` clause by throwing a different error. -In addition, -the `catch` clause must handle -only errors thrown by one of the rethrowing function's -throwing parameters. -For example, the following is invalid -because the `catch` clause would handle -the error thrown by `alwaysThrows()`. +重新抛出的函数或方法只能在 `catch` 子句中包含 `throw` 语句。这使得您可以在 `do`-`catch` 语句中调用抛出函数,并通过抛出不同的错误在 `catch` 子句中处理错误。此外,`catch` 子句必须仅处理由重新抛出函数的抛出参数抛出的错误。例如,以下是无效的,因为 `catch` 子句将处理由 `alwaysThrows()` 抛出的错误。 ```swift func alwaysThrows() throws { @@ -1205,13 +1208,9 @@ func someFunction(callback: () throws -> Void) rethrows { ``` --> -A throwing method can't override a rethrowing method, -and a throwing method can't satisfy a protocol requirement for a rethrowing method. -That said, a rethrowing method can override a throwing method, -and a rethrowing method can satisfy a protocol requirement for a throwing method. +抛出方法不能覆盖重新抛出方法,抛出方法也不能满足重新抛出方法的协议要求。也就是说,重新抛出方法可以覆盖抛出方法,重新抛出方法可以满足抛出方法的协议要求。 -An alternative to rethrowing is throwing a specific error type in generic code. -For example: +在泛型代码中,抛出特定错误类型是重新抛出的替代方案。例如: ```swift func someFunction(callback: () throws(E) -> Void) throws(E) { @@ -1219,11 +1218,7 @@ func someFunction(callback: () throws(E) -> Void) throws(E) { } ``` -This approach to propagating an error -preserves type information about the error. -However, unlike marking a function `rethrows`, -this approach doesn't prevent the function -from throwing an error of the same type. +这种传播错误的方法保留了关于错误的类型信息。然而,与标记一个函数 `rethrows` 不同,这种方法并不阻止该函数抛出相同类型的错误。 -### Asynchronous Functions and Methods +### 异步函数和方法 -Functions and methods that run asynchronously must be marked with the `async` keyword. -These functions and methods are known as *asynchronous functions* -and *asynchronous methods*. -They have the following form: +运行异步的函数和方法必须标记为 `async` 关键字。这些函数和方法被称为 *异步函数* 和 *异步方法*。它们具有以下形式: ```swift func <#function name#>(<#parameters#>) async -> <#return type#> { - <#statements#> + <#statements#> } ``` -Calls to an asynchronous function or method -must be wrapped in an `await` expression --- -that is, they must be in the scope of an `await` operator. +对异步函数或方法的调用必须包装在一个 `await` 表达式中 --- 也就是说,它们必须在 `await` 操作符的作用域内。 -The `async` keyword is part of the function's type, -and synchronous functions are subtypes of asynchronous functions. -As a result, you can use a synchronous function -in a context where an asynchronous function is expected. -For example, -you can override an asynchronous method with a synchronous method, -and a synchronous method can satisfy a protocol requirement -that requires an asynchronous method. - -You can overload a function based on whether or not the function is asynchronous. -At the call site, context determines which overload is used: -In an asynchronous context, the asynchronous function is used, -and in a synchronous context, the synchronous function is used. - -An asynchronous method can't override a synchronous method, -and an asynchronous method can't satisfy a protocol requirement for a synchronous method. -That said, a synchronous method can override an asynchronous method, -and a synchronous method can satisfy a protocol requirement for an asynchronous method. +`async` 关键字是函数类型的一部分,同步函数是异步函数的子类型。因此,您可以覆盖异在期望异步函数的上下文中使用同步函数。例如,您可以用同步方法步方法,并且同步方法可以满足需要异步方法的协议要求。 + +您可以根据函数是否是异步的来重载函数。在调用位置,上下文决定使用哪个重载:在异步上下文中,使用异步函数;在同步上下文中,使用同步函数。 + +一异步方法不能覆盖同步方法,异步方法也不能满足同步方法的协议要求。也就是说,同步方法可以覆盖异步方法,且同步方法可以满足异步方法的协议要求。 -### Functions that Never Return - -Swift defines a [`Never`][] type, -which indicates that a function or method doesn't return to its caller. -Functions and methods with the `Never` return type are called *nonreturning*. -Nonreturning functions and methods either cause an irrecoverable error -or begin a sequence of work that continues indefinitely. -This means that -code that would otherwise run immediately after the call is never executed. -Throwing and rethrowing functions can transfer program control -to an appropriate `catch` block, even when they're nonreturning. +### 永不返回的函数 + +Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返回给调用者。具有 `Never` 返回类型的函数和方法被称为 *非返回*。非返回的函数和方法要么导致不可恢复的错误,要么开始一个无限进行的工作序列。这意味着在调用后立即运行的代码永远不会被执行。抛出和重新抛出的函数可以将程序控制转移到适当的 `catch` 块,即使它们是非返回的。 [`Never`]: https://developer.apple.com/documentation/swift/never -A nonreturning function or method can be called to conclude the `else` clause -of a guard statement, -as discussed in . +不返回的函数或方法可以被调用,以结束守卫语句的 `else` 子句,如在 中讨论的。 -You can override a nonreturning method, -but the new method must preserve its return type and nonreturning behavior. +您可以重写一个不返回的方法,但新方法必须保持其返回类型和不返回值的行为。 -> Grammar of a function declaration: +> 函数声明的语法: > -> *function-declaration* → *function-head* *function-name* *generic-parameter-clause*_?_ *function-signature* *generic-where-clause*_?_ *function-body*_?_ +> *函数声明* → *函数头* *函数名称* *泛型参数子句*_?_ *函数签名* *泛型约束子句*_?_ *函数主体*_?_ > -> *function-head* → *attributes*_?_ *declaration-modifiers*_?_ **`func`** \ -> *function-name* → *identifier* | *operator* +> *函数头* → *属性*_?_ *声明修饰符*_?_ **`func`** \ +> *函数名* → *标识符* | *运算符* > -> *function-signature* → *parameter-clause* **`async`**_?_ *throws-clause*_?_ *function-result*_?_ \ -> *function-signature* → *parameter-clause* **`async`**_?_ **`rethrows`** *function-result*_?_ \ -> *function-result* → **`->`** *attributes*_?_ *type* \ -> *function-body* → *code-block* +> *函数签名* → *参数子句* **`异步`**_?_ *抛出子句*_?_ *函数结果*_?_ \ +> *函数签名* → *参数子句* **`async`**_?_ **`rethrows`** *函数结果*_?_ \ +> *函数结果* → **`->`** *属性*_?_ *类型* \ +> *函数体* → *代码块* > -> *parameter-clause* → **`(`** **`)`** | **`(`** *parameter-list* **`)`** \ -> *parameter-list* → *parameter* | *parameter* **`,`** *parameter-list* \ -> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* *default-argument-clause*_?_ \ -> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* \ -> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* **`...`** +> *参数子句* → **`(`** **`)`** | **`(`** *参数列表* **`)`** \ +> *参数列表* → *参数* | *参数* **`,`** *参数列表* \ +> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* *默认参数子句*_?_ \ +> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* \ +> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* **`...`** > -> *external-parameter-name* → *identifier* \ -> *local-parameter-name* → *identifier* \ -> *parameter-type-annotation* → **`:`** *attributes*_?_ *parameter-modifier*_?_ *type* \ -> *parameter-modifier* → **`inout`** | **`borrowing`** | **`consuming`** -> *default-argument-clause* → **`=`** *expression* +> *外部参数名称* → *标识符* \ +> *局部参数名称* → *标识符* \ +> *参数类型注解* → **`:`** *属性*_?_ *参数修饰符*_?_ *类型* \ +> *参数修饰符* → **`输入输出`** | **`借用`** | **`消耗`** *默认参数子句* → **`=`** *表达式* -## Enumeration Declaration - -An *enumeration declaration* introduces a named enumeration type into your program. - -Enumeration declarations have two basic forms and are declared using the `enum` keyword. -The body of an enumeration declared using either form contains -zero or more values --- called *enumeration cases* --- -and any number of declarations, -including computed properties, -instance methods, type methods, initializers, type aliases, -and even other enumeration, structure, class, and actor declarations. -Enumeration declarations can't contain deinitializer or protocol declarations. - -Enumeration types can adopt any number of protocols, but can’t inherit from classes, -structures, or other enumerations. - -Unlike classes and structures, -enumeration types don't have an implicitly provided default initializer; -all initializers must be declared explicitly. Initializers can delegate -to other initializers in the enumeration, but the initialization process is complete -only after an initializer assigns one of the enumeration cases to `self`. - -Like structures but unlike classes, enumerations are value types; -instances of an enumeration are copied when assigned to -variables or constants, or when passed as arguments to a function call. -For information about value types, -see . +## 枚举声明 -You can extend the behavior of an enumeration type with an extension declaration, -as discussed in . +一个*枚举声明*将一个命名的枚举类型引入到你的程序中。 + +枚举声明有两种基本形式,并使用 `enum` 关键字进行声明。使用任一形式声明的枚举的主体包含零个或多个值 --- 称为 *枚举案例* --- 以及任意数量的声明,包括计算属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor 声明。枚举声明不能包含析构器或协议声明。 + +枚举类型可以采用任意数量的协议,但不能从类、结构或其他枚举继承。 + +与类和结构体不同,枚举类型没有隐式提供的默认构造器;所有构造器必须显式声明。构造器可以委托给枚举中的其他构造器,但初始化过程只有在构造器将枚举的一个案例分配给 `self` 后才完成。 + +像结构体但不同于类,枚举是值类型;当枚举的实例被赋值给变量或常量,或作为参数传递给函数调用时,会被复制。有关值类型的信息,请参见 。 + +您可以通过扩展声明扩展枚举类型的行为,如 中所讨论的。 ### Enumerations with Cases of Any Type From 3dcc14ca0f4bf19a23fa51f145ba23848e494862 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 26 Aug 2024 19:35:59 +0800 Subject: [PATCH 24/67] wip: Enumerations with Cases of Any Type --- .../ReferenceManual/Declarations.md | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 9a9bc4e1..2da26f40 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1315,10 +1315,9 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 您可以通过扩展声明扩展枚举类型的行为,如 中所讨论的。 -### Enumerations with Cases of Any Type +### 任意类型的枚举案例 -The following form declares an enumeration type that contains -enumeration cases of any type: +以下形式声明了一个枚举类型,其中包含任何类型的枚举案例: ```swift enum <#enumeration name#>: <#adopted protocols#> { @@ -1327,20 +1326,11 @@ enum <#enumeration name#>: <#adopted protocols#> { } ``` -Enumerations declared in this form are sometimes called *discriminated unions* -in other programming languages. +在这种形式中声明的枚举有时在其他编程语言中被称为*区分联合*。 -In this form, each case block consists of the `case` keyword -followed by one or more enumeration cases, separated by commas. -The name of each case must be unique. -Each case can also specify that it stores values of a given type. -These types are specified in the *associated value types* tuple, -immediately following the name of the case. +在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。每个案例的名称必须是唯一的。每个案例还可以指定它存储特定类型的值。这些类型在*关联值类型*元组中指定,紧接在案例名称之后。 -Enumeration cases that store associated values can be used as functions -that create instances of the enumeration with the specified associated values. -And just like functions, -you can get a reference to an enumeration case and apply it later in your code. +存储关联值的枚举案例可以用作函数,这些函数创建具有指定关联值的枚举实例。就像函数一样,您可以获取对枚举案例的引用,并在代码中稍后应用它。 ```swift enum Number { @@ -1377,8 +1367,7 @@ let evenInts: [Number] = [0, 2, 4, 6].map(f) and assert() would require Number to conform to Equatable. --> -For more information and to see examples of cases with associated value types, -see . +有关更多信息以及查看与相关值类型相关的案例示例,请参见 。 #### Enumerations with Indirection From cf86bd4f5ac02c85c402dbe4e1d4c38422952ad5 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 26 Aug 2024 19:40:31 +0800 Subject: [PATCH 25/67] wip: Enumerations with Indirection --- .../ReferenceManual/Declarations.md | 32 +++---------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2da26f40..a57ab531 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1369,26 +1369,11 @@ let evenInts: [Number] = [0, 2, 4, 6].map(f) 有关更多信息以及查看与相关值类型相关的案例示例,请参见 。 -#### Enumerations with Indirection +#### 间接枚举 -Enumerations can have a recursive structure, -that is, they can have cases with associated values -that are instances of the enumeration type itself. -However, instances of enumeration types have value semantics, -which means they have a fixed layout in memory. -To support recursion, -the compiler must insert a layer of indirection. +枚举可以具有递归结构,也就是说,它们可以有与枚举类型本身实例相关联的值的情况。然而,枚举类型的实例具有值语义,这意味着它们在内存中具有固定的布局。为了支持递归,编译器必须插入一层间接性。 -To enable indirection for a particular enumeration case, -mark it with the `indirect` declaration modifier. -An indirect case must have an associated value. - - +要为特定的枚举案例启用间接性,请使用 `indirect` 声明修饰符进行标记。间接案例必须具有相关值。 ```swift enum Tree { @@ -1411,16 +1396,9 @@ enum Tree { ``` --> -To enable indirection for all the cases of an enumeration -that have an associated value, -mark the entire enumeration with the `indirect` modifier --- -this is convenient when the enumeration contains many cases -that would each need to be marked with the `indirect` modifier. +要为所有具有关联值的枚举案例启用间接引用,请使用 `indirect` 修饰符标记整个枚举 --- 当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 -An enumeration that's marked with the `indirect` modifier -can contain a mixture of cases that have associated values and cases those that don't. -That said, -it can't contain any cases that are also marked with the `indirect` modifier. +一个标记为 `indirect` 修饰符的枚举可以包含具有关联值的情况和没有关联值的情况的混合。然而,它不能包含任何也标记为 `indirect` 修饰符的案例。 -### Enumerations with Cases of a Raw-Value Type +### 带有原始值类型的枚举 -The following form declares an enumeration type that contains -enumeration cases of the same basic type: +以下表单声明了一个枚举类型,其中包含相同基本类型的枚举案例: ```swift enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { @@ -1441,32 +1440,14 @@ enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { } ``` -In this form, each case block consists of the `case` keyword, -followed by one or more enumeration cases, separated by commas. -Unlike the cases in the first form, each case has an underlying -value, called a *raw value*, of the same basic type. -The type of these values is specified in the *raw-value type* and must represent an -integer, floating-point number, string, or single character. -In particular, the *raw-value type* must conform to the `Equatable` protocol -and one of the following protocols: -`ExpressibleByIntegerLiteral` for integer literals, -`ExpressibleByFloatLiteral` for floating-point literals, -`ExpressibleByStringLiteral` for string literals that contain any number of characters, -and `ExpressibleByUnicodeScalarLiteral` -or `ExpressibleByExtendedGraphemeClusterLiteral` for string literals -that contain only a single character. -Each case must have a unique name and be assigned a unique raw value. +在这种形式中,每个案例块由`case`关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。与第一种形式中的案例不同,每个案例都有一个基础值,称为*原始值*,其基本类型相同。这些值的类型在*原始值类型*中指定,必须表示整数、浮点数、字符串或单个字符。特别是,*原始值类型*必须符合`Equatable`协议,并且符合以下协议之一:`ExpressibleByIntegerLiteral` 用于整数字面量,`ExpressibleByFloatLiteral` 用于浮点字面量,`ExpressibleByStringLiteral` 用于包含任意数量字符的字符串字面量,以及 `ExpressibleByUnicodeScalarLiteral` 或 `ExpressibleByExtendedGraphemeClusterLiteral` 用于仅包含单个字符的字符串字面量。每个案例必须具有唯一名称并分配唯一的原始值。 -If the raw-value type is specified as `Int` -and you don't assign a value to the cases explicitly, -they're implicitly assigned the values `0`, `1`, `2`, and so on. -Each unassigned case of type `Int` is implicitly assigned a raw value -that's automatically incremented from the raw value of the previous case. +如果原始值类型被指定为 `Int`,并且您没有显式地为这些情况分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的情况将隐式地被分配一个原始值,该值是从前一个案例的原始值自动递增的。 ```swift enum ExampleEnum: Int { @@ -1484,14 +1465,9 @@ enum ExampleEnum: Int { ``` --> -In the above example, the raw value of `ExampleEnum.a` is `0` and the value of -`ExampleEnum.b` is `1`. And because the value of `ExampleEnum.c` is -explicitly set to `5`, the value of `ExampleEnum.d` is automatically incremented -from `5` and is therefore `6`. +在上述示例中,`ExampleEnum.a` 的原始值为 `0`,而 `ExampleEnum.b` 的值为 `1`。由于 `ExampleEnum.c` 的值被显式设置为 `5`,因此 `ExampleEnum.d` 的值自动从 `5` 增加,结果为 `6`。 -If the raw-value type is specified as `String` -and you don't assign values to the cases explicitly, -each unassigned case is implicitly assigned a string with the same text as the name of that case. +如果原始值类型被指定为 `String`,并且您没有显式地为各个情况分配值,则每个未分配的案例会隐式地分配一个与该案例名称相同文本的字符串。 ```swift enum GamePlayMode: String { @@ -1509,21 +1485,7 @@ enum GamePlayMode: String { ``` --> -In the above example, the raw value of `GamePlayMode.cooperative` is `"cooperative"`, -the raw value of `GamePlayMode.individual` is `"individual"`, -and the raw value of `GamePlayMode.competitive` is `"competitive"`. - -Enumerations that have cases of a raw-value type implicitly conform to the -`RawRepresentable` protocol, defined in the Swift standard library. -As a result, they have a `rawValue` property -and a failable initializer with the signature `init?(rawValue: RawValue)`. -You can use the `rawValue` property to access the raw value of an enumeration case, -as in `ExampleEnum.b.rawValue`. -You can also use a raw value to find a corresponding case, if there is one, -by calling the enumeration's failable initializer, -as in `ExampleEnum(rawValue: 5)`, which returns an optional case. -For more information and to see examples of cases with raw-value types, -see . +在上述示例中,`GamePlayMode.cooperative` 的原始值是 `"cooperative"`,`GamePlayMode.individual` 的原始值是 `"individual"`,而 `GamePlayMode.competitive` 的原始值是 `"competitive"`。 ### Accessing Enumeration Cases From bfcdb7c34e87bf18c2bf0c0ed3617c80b94dcd28 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 26 Aug 2024 19:59:27 +0800 Subject: [PATCH 27/67] wip: Accessing Enumeration Cases --- .../ReferenceManual/Declarations.md | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 76168497..6854056a 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1487,19 +1487,13 @@ enum GamePlayMode: String { 在上述示例中,`GamePlayMode.cooperative` 的原始值是 `"cooperative"`,`GamePlayMode.individual` 的原始值是 `"individual"`,而 `GamePlayMode.competitive` 的原始值是 `"competitive"`。 -### Accessing Enumeration Cases +具有原始值类型的枚举隐式符合在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败的构造器,其签名为 `init?(rawValue: RawValue)`。您可以使用 `rawValue` 属性访问枚举案例的原始值,如 `ExampleEnum.b.rawValue`。您还可以使用原始值通过调用枚举的可失败构造器来查找相应的案例(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 -To reference the case of an enumeration type, use dot (`.`) syntax, -as in `EnumerationType.enumerationCase`. When the enumeration type can be inferred -from context, you can omit it (the dot is still required), -as described in -and . +### 访问枚举案例 -To check the values of enumeration cases, use a `switch` statement, -as shown in . -The enumeration type is pattern-matched against the enumeration case patterns -in the case blocks of the `switch` statement, -as described in . +要引用枚举类型的案例,请使用点(`.`)语法,如`EnumerationType.enumerationCase`所示。当枚举类型可以从上下文中推断时,可以省略它(仍然需要点),如 中所述。 + +要检查枚举案例的值,请使用 `switch` 语句,如 中所示。枚举类型与 `switch` 语句的案例块中的枚举案例模式进行模式匹配,如 中所述。 -> Grammar of an enumeration declaration: +> 枚举声明的语法: > -> *enum-declaration* → *attributes*_?_ *access-level-modifier*_?_ *union-style-enum* \ -> *enum-declaration* → *attributes*_?_ *access-level-modifier*_?_ *raw-value-style-enum* +> *枚举声明* → *属性*_?_ *访问级别修饰符*_?_ *联合样式枚举* \ +> *枚举声明* → *属性*_?_ *访问级别修饰符*_?_ *原始值样式枚举* > -> *union-style-enum* → **`indirect`**_?_ **`enum`** *enum-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ **`{`** *union-style-enum-members*_?_ **`}`** \ -> *union-style-enum-members* → *union-style-enum-member* *union-style-enum-members*_?_ \ -> *union-style-enum-member* → *declaration* | *union-style-enum-case-clause* | *compiler-control-statement* \ -> *union-style-enum-case-clause* → *attributes*_?_ **`indirect`**_?_ **`case`** *union-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-name* *tuple-type*_?_ \ -> *enum-name* → *identifier* \ -> *enum-case-name* → *identifier* +> *联合样式枚举* → **`间接`**_?_ **`枚举`** *枚举名称* *泛型参数子句*_?_ *类型继承子句*_?_ *泛型约束子句*_?_ **`{`** *联合样式枚举成员*_?_ **`}`** \ +> *联合体样式枚举成员* → *联合体样式枚举成员* *联合体样式枚举成员*_?_ \ +> *联合体风格枚举成员* → *声明* | *联合体风格枚举案例子句* | *编译器控制语句* \ +> *联合样式枚举案例子句* → *属性*_?_ **`间接`**_?_ **`案例`** *联合样式枚举案例列表* \ +> *联合样式枚举案例列表* → *联合样式枚举案例* | *联合样式枚举案例* **`,`** *联合样式枚举案例列表* \ +> *联合样式枚举案例* → *枚举案例名称* *元组类型*_?_ \ +> *枚举名称* → *标识符* \ +> *枚举案例名称* → *标识符* > -> *raw-value-style-enum* → **`enum`** *enum-name* *generic-parameter-clause*_?_ *type-inheritance-clause* *generic-where-clause*_?_ **`{`** *raw-value-style-enum-members* **`}`** \ -> *raw-value-style-enum-members* → *raw-value-style-enum-member* *raw-value-style-enum-members*_?_ \ -> *raw-value-style-enum-member* → *declaration* | *raw-value-style-enum-case-clause* | *compiler-control-statement* \ -> *raw-value-style-enum-case-clause* → *attributes*_?_ **`case`** *raw-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-name* *raw-value-assignment*_?_ \ -> *raw-value-assignment* → **`=`** *raw-value-literal* \ -> *raw-value-literal* → *numeric-literal* | *static-string-literal* | *boolean-literal* +> *原始值样式枚举* → **`枚举`** *枚举名称* *泛型参数子句*_?_ *类型继承子句* *泛型约束子句*_?_ **`{`** *原始值样式枚举成员* **`}`** \ +> *原始值样式枚举成员* → *原始值样式枚举成员* *原始值样式枚举成员*_?_ \ +> *原始值样式枚举成员* → *声明* | *原始值样式枚举案例条款* | *编译器控制语句* \ +> *原始值样式枚举案例条款* → *属性*_?_ **`案例`** *原始值样式枚举案例列表* \ +> *原始值样式枚举案例列表* → *原始值样式枚举案例* | *原始值样式枚举案例* **`,`** *原始值样式枚举案例列表* \ +> *原始值样式枚举案例* → *枚举案例名称* *原始值赋值*_?_ \ +> *原始值赋值* → **`=`** *原始值字面量* \ +> *原始值字面量* → *数值字面量* | *静态字符串字面量* | *布尔字面量* -## Structure Declaration +## 结构体声明 -A *structure declaration* introduces a named structure type into your program. -Structure declarations are declared using the `struct` keyword and have the following form: +*结构体声明*将一个命名的结构体类型引入到你的程序中。结构体声明使用 `struct` 关键字声明,具有以下形式: ```swift struct <#structure name#>: <#adopted protocols#> { - <#declarations#> + <#declarations#> } ``` -The body of a structure contains zero or more *declarations*. -These *declarations* can include both stored and computed properties, -type properties, instance methods, type methods, initializers, subscripts, -type aliases, and even other structure, class, actor, and enumeration declarations. -Structure declarations can't contain deinitializer or protocol declarations. -For a discussion and several examples of structures -that include various kinds of declarations, -see . +结构体的主体包含零个或多个*声明*。这些*声明*可以包括存储属性和计算属性、类型属性、实例方法、类型方法、构造器、下标、类型别名,甚至其他结构体、类、actor 和枚举声明。结构声明不能包含析构器或协议声明。有关包含各种类型声明的结构的讨论和多个示例,请参见 。 -Structure types can adopt any number of protocols, -but can't inherit from classes, enumerations, or other structures. +结构体类型可以采用任意数量的协议,但不能从类、枚举或其他结构继承。 -There are three ways to create an instance of a previously declared structure: +有三种方法可以创建先前声明的结构体的实例: -- Call one of the initializers declared within the structure, - as described in . -- If no initializers are declared, - call the structure's memberwise initializer, - as described in . -- If no initializers are declared, - and all properties of the structure declaration were given initial values, - call the structure's default initializer, - as described in . +- 调用结构体中声明的某个构造器,如 中所述。 +- 如果没有声明构造器,则调用结构体的成员遍历构造器,如 中所述。 +- 如果没有声明构造器,且结构体声明的所有属性都给定了初始值,则调用结构体的默认构造器,如 中所述。 -The process of initializing a structure's declared properties -is described in . +初始化结构体中声明属性的过程在 中描述。 -Properties of a structure instance can be accessed using dot (`.`) syntax, -as described in . +结构体实例的属性可以使用点 (`.`) 语法访问,如 中所述。 -Structures are value types; instances of a structure are copied when assigned to -variables or constants, or when passed as arguments to a function call. -For information about value types, -see . +结构体是值类型;当结构的实例被赋值给变量或常量,或作为参数传递给函数调用时,会被复制。有关值类型的信息,请参见 。 -You can extend the behavior of a structure type with an extension declaration, -as discussed in . +您可以通过扩展声明扩展结构类型的行为,如在 中讨论的。 -> Grammar of a structure declaration: +> 结构体声明的语法: > -> *struct-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`struct`** *struct-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *struct-body* \ -> *struct-name* → *identifier* \ -> *struct-body* → **`{`** *struct-members*_?_ **`}`** +> *结构声明* → *属性*_?_ *访问级别修饰符*_?_ **`struct`** *结构名称* *泛型参数子句*_?_ *类型继承子句*_?_ *泛型约束子句*_?_ *结构体主体* \ +> *结构名称* → *标识符* \ +> *结构体主体* → **`{`** *结构体成员*_?_ **`}`** > -> *struct-members* → *struct-member* *struct-members*_?_ \ -> *struct-member* → *declaration* | *compiler-control-statement* +> *结构成员* → *结构成员* *结构成员*_?_ \ +> *结构成员* → *声明* | *编译器控制语句* ## Class Declaration From b02e33ef06a4a55cc9d18d4806dc91724f69cb3f Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 00:59:00 +0800 Subject: [PATCH 29/67] wip: Class Declaration --- .../ReferenceManual/Declarations.md | 83 +++++-------------- 1 file changed, 22 insertions(+), 61 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2fee474c..0aad0adb 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1592,46 +1592,23 @@ struct <#structure name#>: <#adopted protocols#> { > *结构成员* → *结构成员* *结构成员*_?_ \ > *结构成员* → *声明* | *编译器控制语句* -## Class Declaration +## 类声明 -A *class declaration* introduces a named class type into your program. -Class declarations are declared using the `class` keyword and have the following form: +*类声明*将一个命名的类类型引入到你的程序中。类声明使用 `class` 关键字声明,具有以下形式: ```swift class <#class name#>: <#superclass#>, <#adopted protocols#> { - <#declarations#> + <#declarations#> } ``` -The body of a class contains zero or more *declarations*. -These *declarations* can include both stored and computed properties, -instance methods, type methods, initializers, -a single deinitializer, subscripts, type aliases, -and even other class, structure, actor, and enumeration declarations. -Class declarations can't contain protocol declarations. -For a discussion and several examples of classes -that include various kinds of declarations, -see . +类的主体包含零个或多个*声明*。这些*声明*可以包括存储属性和计算属性、实例方法、类型方法、构造器、一个析构器、下标、类型别名,甚至其他类、结构、action 和枚举声明。类声明不能包含协议声明。有关包含各种类型声明的类的讨论和多个示例,请参见 。 -A class type can inherit from only one parent class, its *superclass*, -but can adopt any number of protocols. -The *superclass* appears first after the *class name* and colon, -followed by any *adopted protocols*. -Generic classes can inherit from other generic and nongeneric classes, -but a nongeneric class can inherit only from other nongeneric classes. -When you write the name of a generic superclass class after the colon, -you must include the full name of that generic class, -including its generic parameter clause. +一个类类型只能继承自一个父类,即它的*超类*,但可以采用任意数量的协议。*超类*在*类名*和冒号之后首先出现,后面跟着任何*采用的协议*。泛型类可以继承其他泛型和非泛型类,但非泛型类只能继承其他非泛型类。当你在冒号后写泛型超类的名称时,必须包括该泛型类的全名,包括其泛型参数子句。 -As discussed in , -classes can have designated and convenience initializers. -The designated initializer of a class must initialize all of the class's -declared properties and it must do so before calling any of its superclass's -designated initializers. +如在 中讨论的,类可以有指定构造器和便利构造器。类的指定构造器必须初始化所有声明的属性,并且必须在调用任何超类的指定构造器之前完成此操作。 -A class can override properties, methods, subscripts, and initializers of its superclass. -Overridden properties, methods, subscripts, -and designated initializers must be marked with the `override` declaration modifier. +一个类可以重写其超类的属性、方法、下标和构造器。重写的属性、方法、下标和指定构造器必须标记为 `override` 声明修饰符。 -To require that subclasses implement a superclass's initializer, -mark the superclass's initializer with the `required` declaration modifier. -The subclass's implementation of that initializer -must also be marked with the `required` declaration modifier. +要要求子类实现超类的构造器,请使用 `required` 声明修饰符标记超类的构造器。子类对该构造器的实现也必须使用 `required` 声明修饰符进行标记。 -Although properties and methods declared in the *superclass* are inherited by -the current class, designated initializers declared in the *superclass* are only -inherited when the subclass meets the conditions described in -. -Swift classes don't inherit from a universal base class. +尽管在*超类*中声明的属性和方法被当前类继承,但在*超类*中声明的指定构造器仅在子类满足 中描述的条件时才会被继承。Swift 类不从通用基类继承。 -There are two ways to create an instance of a previously declared class: +有两种方法可以创建一个先前声明的类的实例: -- Call one of the initializers declared within the class, - as described in . -- If no initializers are declared, - and all properties of the class declaration were given initial values, - call the class's default initializer, - as described in . +- 调用类中声明的某个构造器,如 中所述。 +- 如果没有声明构造器,且类声明的所有属性都给定了初始值,则调用类的默认构造器,如 中所述。 -Access properties of a class instance with dot (`.`) syntax, -as described in . +使用点(`.`)语法访问类实例的属性,如 中所述。 -Classes are reference types; instances of a class are referred to, rather than copied, -when assigned to variables or constants, or when passed as arguments to a function call. -For information about reference types, -see . +类是引用类型;当类的实例被赋值给变量或常量,或作为参数传递给函数调用时,是引用而不是复制。有关引用类型的信息,请参见 。 -You can extend the behavior of a class type with an extension declaration, -as discussed in . +您可以通过扩展声明扩展类类型的行为,如 中所讨论的。 -> Grammar of a class declaration: +> 类声明的语法: > -> *class-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`final`**_?_ **`class`** *class-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *class-body* \ -> *class-declaration* → *attributes*_?_ **`final`** *access-level-modifier*_?_ **`class`** *class-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *class-body* \ -> *class-name* → *identifier* \ -> *class-body* → **`{`** *class-members*_?_ **`}`** +> *类声明* → *属性*_?_ *访问级别修饰符*_?_ **`最终`**_?_ **`类`** *类名* *泛型参数子句*_?_ *类型继承子句*_?_ *泛型约束子句*_?_ *类主体* \ +> *类声明* → *属性*_?_ **`最终`** *访问级别修饰符*_?_ **`类`** *类名* *泛型参数子句*_?_ *类型继承子句*_?_ *泛型约束子句*_?_ *类体* \ +> *类名* → *标识符* \ +> *类主体* → **`{`** *类成员*_?_ **`}`** > -> *class-members* → *class-member* *class-members*_?_ \ -> *class-member* → *declaration* | *compiler-control-statement* +> *类成员* → *类成员* *类成员*_?_ \ +> *类成员* → *声明* | *编译器控制语句* ## Actor Declaration From 65255fa6c27da39a7f02511a20a6ade1d05860c7 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 13:00:34 +0800 Subject: [PATCH 30/67] wip: Actor Declaration --- .../ReferenceManual/Declarations.md | 78 +++++-------------- 1 file changed, 21 insertions(+), 57 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 0aad0adb..9c1106b0 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1644,10 +1644,9 @@ class <#class name#>: <#superclass#>, <#adopted protocols#> { > *类成员* → *类成员* *类成员*_?_ \ > *类成员* → *声明* | *编译器控制语句* -## Actor Declaration +## Actor 声明 -An *actor declaration* introduces a named actor type into your program. -Actor declarations are declared using the `actor` keyword and have the following form: +一个*actor 声明*将一个命名的actor类型引入到您的程序中。actor 声明使用 `actor` 关键字声明,具有以下形式: ```swift actor <#actor name#>: <#adopted protocols#> { @@ -1655,64 +1654,29 @@ actor <#actor name#>: <#adopted protocols#> { } ``` -The body of an actor contains zero or more *declarations*. -These *declarations* can include both stored and computed properties, -instance methods, type methods, initializers, -a single deinitializer, subscripts, type aliases, -and even other class, structure, and enumeration declarations. -For a discussion and several examples of actors -that include various kinds of declarations, -see . -Actor types can adopt any number of protocols, -but can't inherit from classes, enumerations, structures, or other actors. -However, an actor that is marked with the `@objc` attribute -implicitly conforms to the `NSObjectProtocol` protocol -and is exposed to the Objective-C runtime as a subtype of `NSObject`. +actor 的主体包含零个或多个*声明*。这些*声明*可以包括存储属性和计算属性、实例方法、类型方法、构造器、一个析构器、下标、类型别名,甚至其他类、结构体和枚举声明。有关包含各种声明的 actor 的讨论和多个示例,请参见 。 -There are two ways to create an instance of a previously declared actor: +actor 类型可以采用任意数量的协议,但不能从类、枚举、结构体或其他actor继承。然而,标记为 `@objc` 属性的 actor 隐式地符合 `NSObjectProtocol` 协议,并作为 `NSObject` 的子类型暴露给 Objective-C 运行时。 -- Call one of the initializers declared within the actor, - as described in . -- If no initializers are declared, - and all properties of the actor declaration were given initial values, - call the actor's default initializer, - as described in . +有两种方法可以创建一个先前声明的actor的实例: -By default, members of an actor are isolated to that actor. -Code, such as the body of a method or the getter for a property, -is executed on that actor. -Code within the actor can interact with them synchronously -because that code is already running on the same actor, -but code outside the actor must mark them with `await` -to indicate that this code is asynchronously running code on another actor. -Key paths can't refer to isolated members of an actor. -Actor-isolated stored properties can be passed as in-out parameters -to synchronous functions, -but not to asynchronous functions. +- 调用 actor 中声明的某个构造方法,如 中所述。 +- 如果没有声明初始值,并且 actor 声明的所有属性都给定了初始值,则调用 actor 的默认构造器,如 中所述。 -Actors can also have nonisolated members, -whose declarations are marked with the `nonisolated` keyword. -A nonisolated member executes like code outside of the actor: -It can't interact with any of the actor's isolated state, -and callers don't mark it with `await` when using it. +默认情况下,actor 的成员是与该 actor 隔离的。代码,例如方法的主体或属性的 getter,是在该actor上执行的。actor 内部的代码可以与它们同步交互,因为该代码已经在同一个 actor 上运行,但 actor 外部的代码必须用 `await` 标记它们,以指示该代码是异步在另一个 actor 上运行的。关键路径不能引用 actor 的隔离成员。actor 隔离的存储属性可以作为输入输出参数传递给同步函数,但不能传递给异步函数。 -Members of an actor can be marked with the `@objc` attribute -only if they are nonisolated or asynchronous. +actor 还可以拥有非隔离成员,其声明使用 `nonisolated` 关键字标记。非隔离成员的执行方式类似于actor外部的代码:它无法与 actor 的任何隔离状态交互,调用者在使用时也不需要使用 `await` 进行标记。 -The process of initializing an actor's declared properties -is described in . +actor 的成员只有在它们是非隔离或异步的情况下才能标记为 `@objc` 属性。 -Properties of an actor instance can be accessed using dot (`.`) syntax, -as described in . +初始化 actor 中声明的属性的过程在 中描述。 -Actors are reference types; instances of an actor are referred to, rather than copied, -when assigned to variables or constants, or when passed as arguments to a function call. -For information about reference types, -see . +actor 实例的属性可以使用点 (`.`) 语法访问,如 中所述。 -You can extend the behavior of an actor type with an extension declaration, -as discussed in . +actor 是引用类型;当分配给变量或常量,或作为参数传递给函数调用时,actor的实例是被引用而不是复制。有关引用类型的信息,请参见 。 + +您可以通过扩展声明扩展 actor 类型的行为,如 中所讨论的。 -> Grammar of an actor declaration: +> actor 声明的语法: > -> *actor-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`actor`** *actor-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *actor-body* \ -> *actor-name* → *identifier* \ -> *actor-body* → **`{`** *actor-members*_?_ **`}`** +> *actor声明* → *属性*_?_ *访问级别修饰符*_?_ **`actor`** *actor名称* *泛型参数子句*_?_ *类型继承子句*_?_ *泛型约束子句*_?_ *actor主体* \ +> *actor姓名* → *标识符* +> *actor主体* → **`{`** *actor成员*_?_ **`}`** \ > -> *actor-members* → *actor-member* *actor-members*_?_ \ -> *actor-member* → *declaration* | *compiler-control-statement* +> *actor-成员* → *actor-成员* *actor-成员*_?_ \ +> *actor-成员* → *声明* | *编译器控制语句* ## Protocol Declaration From 18a970c7ce9359d1db5e6ba3807255347514f944 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 14:43:49 +0800 Subject: [PATCH 31/67] wip: Protocol Declaration --- .../ReferenceManual/Declarations.md | 128 +++++------------- 1 file changed, 35 insertions(+), 93 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 9c1106b0..6cfa8e4f 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1695,63 +1695,27 @@ actor 是引用类型;当分配给变量或常量,或作为参数传递给 > *actor-成员* → *actor-成员* *actor-成员*_?_ \ > *actor-成员* → *声明* | *编译器控制语句* -## Protocol Declaration +## 协议声明 -A *protocol declaration* introduces a named protocol type into your program. -Protocol declarations are declared -using the `protocol` keyword and have the following form: +*协议声明*将一个命名的协议类型引入到您的程序中。协议声明使用 `protocol` 关键字声明,具有以下形式: ```swift protocol <#protocol name#>: <#inherited protocols#> { - <#protocol member declarations#> -} -``` - -Protocol declarations can appear at global scope, -or nested inside a nongeneric type or nongeneric function. - -The body of a protocol contains zero or more *protocol member declarations*, -which describe the conformance requirements that any type adopting the protocol must fulfill. -In particular, a protocol can declare that conforming types must -implement certain properties, methods, initializers, and subscripts. -Protocols can also declare special kinds of type aliases, -called *associated types*, that can specify relationships -among the various declarations of the protocol. -Protocol declarations can't contain -class, structure, enumeration, or other protocol declarations. -The *protocol member declarations* are discussed in detail below. - -Protocol types can inherit from any number of other protocols. -When a protocol type inherits from other protocols, -the set of requirements from those other protocols are aggregated, -and any type that inherits from the current protocol must conform to all those requirements. -For an example of how to use protocol inheritance, -see . - -> Note: You can also aggregate the conformance requirements of multiple -> protocols using protocol composition types, -> as described in -> and . - -You can add protocol conformance to a previously declared type -by adopting the protocol in an extension declaration of that type. -In the extension, you must implement all of the adopted protocol's -requirements. If the type already implements all of the requirements, -you can leave the body of the extension declaration empty. - -By default, types that conform to a protocol must implement all -properties, methods, and subscripts declared in the protocol. -That said, you can mark these protocol member declarations with the `optional` declaration modifier -to specify that their implementation by a conforming type is optional. -The `optional` modifier can be applied -only to members that are marked with the `objc` attribute, -and only to members of protocols that are marked -with the `objc` attribute. As a result, only class types can adopt and conform -to a protocol that contains optional member requirements. -For more information about how to use the `optional` declaration modifier -and for guidance about how to access optional protocol members --- -for example, when you're not sure whether a conforming type implements them --- -see . + <#protocol member declarations#> +} +``` + +协议声明可以出现在全局范围内,或嵌套在非泛型类型或非泛型函数内部。 + +协议的主体包含零个或多个*协议成员声明*,这些声明描述了任何采用该协议的类型必须满足的符合性要求。特别是,协议可以声明符合的类型必须实现某些属性、方法、构造器和下标。协议还可以声明特殊类型的类型别名,称为*关联类型*,可以指定协议中各种声明之间的关系。协议声明不能包含类、结构体、枚举或其他协议声明。*协议成员声明*将在下面详细讨论。 + +协议类型可以从任意数量的其他协议继承。当一个协议类型从其他协议继承时,这些其他协议的要求集合会被聚合,任何从当前协议继承的类型必须符合所有这些要求。有关如何使用协议继承的示例,请参见 。 + +> 注意:您还可以使用协议组合类型聚合多个协议的合规性要求,如 中所述。 + +您可以通过在该类型的扩展声明中采用协议,为先前声明的类型添加协议符合性。在扩展中,您必须实现所采用协议的所有要求。如果该类型已经实现了所有要求,您可以将扩展声明的主体留空。 + +默认情况下,符合协议的类型必须实现协议中声明的所有属性、方法和下标。也就是说,您可以使用 `optional` 声明修饰符来标记这些协议成员声明,以指定符合类型的实现是可选的。`optional` 修饰符只能应用于标记为 `objc` 属性的成员,并且只能应用于标记为 `objc` 属性的协议成员。因此,只有类类型可以采用并符合包含可选成员要求的协议。有关如何使用 `optional` 声明修饰符的信息,以及如何访问可选协议成员的指导——例如,当您不确定符合类型是否实现它们时 --- 请参见 -The cases of an enumeration can satisfy -protocol requirements for type members. -Specifically, -an enumeration case without any associated values -satisfies a protocol requirement for -a get-only type variable of type `Self`, -and an enumeration case with associated values -satisfies a protocol requirement for a function that returns `Self` -whose parameters and their argument labels -match the case's associated values. -For example: +枚举的案例可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举案例满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举案例满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与案例的关联值匹配。例如: ```swift protocol SomeProtocol { @@ -1799,10 +1753,7 @@ enum MyEnum: SomeProtocol { ``` --> -To restrict the adoption of a protocol to class types only, -include the `AnyObject` protocol in the *inherited protocols* -list after the colon. -For example, the following protocol can be adopted only by class types: +要将协议的采用限制为类类型,只需在冒号后将 `AnyObject` 协议包含在*继承协议*列表中。例如,以下协议只能被类类型采用: ```swift protocol SomeProtocol: AnyObject { @@ -1820,38 +1771,29 @@ protocol SomeProtocol: AnyObject { ``` --> -Any protocol that inherits from a protocol that's marked with the `AnyObject` requirement -can likewise be adopted only by class types. +任何从标记为 `AnyObject` 要求的协议继承的协议,也只能被类类型采用。 -> Note: If a protocol is marked with the `objc` attribute, -> the `AnyObject` requirement is implicitly applied to that protocol; -> there’s no need to mark the protocol with the `AnyObject` requirement explicitly. +> 注意:如果一个协议标记了 `objc` 属性,则 `AnyObject` 要求隐式应用于该协议;无需明确将该协议标记为 `AnyObject` 要求。 -Protocols are named types, and thus they can appear in all the same places -in your code as other named types, as discussed in . -However, -you can't construct an instance of a protocol, -because protocols don't actually provide the implementations for the requirements -they specify. +协议是命名类型,因此它们可以出现在代码中与其他命名类型相同的位置,如 中所讨论的。然而,您无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 -You can use protocols to declare which methods a delegate of a class or structure -should implement, as described in . +您可以使用协议来声明类或结构体的代理应该实现哪些方法,如 中所述。 -> Grammar of a protocol declaration: +> 协议声明的语法: > -> *protocol-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`protocol`** *protocol-name* *type-inheritance-clause*_?_ *generic-where-clause*_?_ *protocol-body* \ -> *protocol-name* → *identifier* \ -> *protocol-body* → **`{`** *protocol-members*_?_ **`}`** +> *协议声明* → *属性*_?_ *访问级别修饰符*_?_ **`协议`** *协议名称* *类型继承条款*_?_ *泛型约束条款*_?_ *协议主体* \ +> *协议名称* → *标识符* \ +> *协议主体* → **`{`** *协议成员*_?_ **`}`** > -> *protocol-members* → *protocol-member* *protocol-members*_?_ \ -> *protocol-member* → *protocol-member-declaration* | *compiler-control-statement* +> *协议成员* → *协议成员* *协议成员*_?_ \ +> *协议成员* → *协议成员声明* | *编译器控制语句* > -> *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-declaration* → *typealias-declaration* +> *协议成员声明* → *协议属性声明* \ +> *协议成员声明* → *协议方法声明* \ +> *协议成员声明* → *协议构造器声明* \ +> *协议成员声明* → *协议下标声明* \ +> *协议成员声明* → *协议关联类型声明* \ +> *协议成员声明* → *类型别名声明* ### Protocol Property Declaration From 3dc5b05326ba3799a277320927bf2d41fa210a8e Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 15:00:21 +0800 Subject: [PATCH 32/67] wip: Protocol Property Declaration --- .../ReferenceManual/Declarations.md | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 6cfa8e4f..97dc8584 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1795,44 +1795,19 @@ protocol SomeProtocol: AnyObject { > *协议成员声明* → *协议关联类型声明* \ > *协议成员声明* → *类型别名声明* -### Protocol Property Declaration +### 协议属性声明 -Protocols declare that conforming types must implement a property -by including a *protocol property declaration* -in the body of the protocol declaration. -Protocol property declarations have a special form of a variable -declaration: +协议声明符合的类型必须通过在协议声明的主体中包含一个*协议属性声明*来实现一个属性。协议属性声明具有变量声明的特殊形式: ```swift var <#property name#>: <#type#> { get set } ``` -As with other protocol member declarations, these property declarations -declare only the getter and setter requirements for types -that conform to the protocol. As a result, you don't implement the getter or setter -directly in the protocol in which it's declared. - -The getter and setter requirements can be satisfied by a conforming type in a variety of ways. -If a property declaration includes both the `get` and `set` keywords, -a conforming type can implement it with a stored variable property -or a computed property that's both readable and writeable -(that is, one that implements both a getter and a setter). However, -that property declaration can't be implemented as a constant property -or a read-only computed property. If a property declaration includes -only the `get` keyword, it can be implemented as any kind of property. -For examples of conforming types that implement the property requirements of a protocol, -see . - -To declare a type property requirement in a protocol declaration, -mark the property declaration with the `static` keyword. -Structures and enumerations that conform to the protocol -declare the property with the `static` keyword, -and classes that conform to the protocol -declare the property with either the `static` or `class` keyword. -Extensions that add protocol conformance to a structure, enumeration, or class -use the same keyword as the type they extend uses. -Extensions that provide a default implementation for a type property requirement -use the `static` keyword. +与其他协议成员声明一样,这些属性声明仅声明符合该协议的类型的 getter 和 setter 要求。因此,您不会在声明它的协议中直接实现 getter 或 setter。 + +getter 和 setter 的要求可以通过符合类型以多种方式满足。如果属性声明同时包含 `get` 和 `set` 关键字,则符合类型可以通过存储变量属性或可读可写的计算属性来实现(即实现了 getter 和 setter 的属性)。然而,该属性声明不能实现为常量属性或只读计算属性。如果属性声明仅包含 `get` 关键字,则可以实现为任何类型的属性。有关实现协议属性要求的符合类型的示例,请参见 。 + +在协议声明中声明类型属性要求时,使用 `static` 关键字标记属性声明。符合该协议的结构体和枚举使用 `static` 关键字声明属性,而符合该协议的类则可以使用 `static` 或 `class` 关键字声明属性。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型属性要求提供默认实现的扩展使用 `static` 关键字。 -See also . +另见 。 -> Grammar of a protocol property declaration: +> 协议属性声明的语法: > -> *protocol-property-declaration* → *variable-declaration-head* *variable-name* *type-annotation* *getter-setter-keyword-block* +> *协议属性声明* → *变量-声明-头* *变量名称* *类型注解* *gettersetter关键字块* ### Protocol Method Declaration From 6ffe978ea3a588da1e4959d98a352996d48c9744 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 15:04:00 +0800 Subject: [PATCH 33/67] wip: Protocol Method Declaration --- .../ReferenceManual/Declarations.md | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 97dc8584..b4a50872 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1849,36 +1849,21 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 > > *协议属性声明* → *变量-声明-头* *变量名称* *类型注解* *gettersetter关键字块* -### Protocol Method Declaration - -Protocols declare that conforming types must implement a method -by including a protocol method declaration in the body of the protocol declaration. -Protocol method declarations have the same form as -function declarations, with two exceptions: They don't include a function body, -and you can't provide any default parameter values as part of the function declaration. -For examples of conforming types that implement the method requirements of a protocol, -see . - -To declare a class or static method requirement in a protocol declaration, -mark the method declaration with the `static` declaration modifier. -Structures and enumerations that conform to the protocol -declare the method with the `static` keyword, -and classes that conform to the protocol -declare the method with either the `static` or `class` keyword. -Extensions that add protocol conformance to a structure, enumeration, or class -use the same keyword as the type they extend uses. -Extensions that provide a default implementation for a type method requirement -use the `static` keyword. +### 协议方法声明 + +协议声明符合类型必须通过在协议声明的主体中包含协议方法声明来实现方法。协议方法声明的形式与函数声明相同,有两个例外:它们不包括函数体,并且您不能在函数声明中提供任何默认参数值。有关实现协议方法要求的符合类型的示例,请参见 。 + +在协议声明中声明类或静态方法的要求时,使用 `static` 修饰符标记方法声明。符合该协议的结构体和枚举使用 `static` 关键字声明该方法,而符合该协议的类则使用 `static` 或 `class` 关键字声明该方法。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型方法要求提供默认实现的扩展使用 `static` 关键字。 -See also . +另见 -> Grammar of a protocol method declaration: +> 协议方法声明的语法: > -> *protocol-method-declaration* → *function-head* *function-name* *generic-parameter-clause*_?_ *function-signature* *generic-where-clause*_?_ +> *协议方法声明* → *函数头* *函数名称* *泛型参数子句*_?_ *函数签名* *泛型约束子句*_?_ ### Protocol Initializer Declaration From 6b80aa98ae33f83769aa4a022bf7507a634484de Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 15:10:26 +0800 Subject: [PATCH 34/67] wip: Protocol Initializer Declaration --- .../ReferenceManual/Declarations.md | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index b4a50872..9d800179 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1865,28 +1865,21 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 > > *协议方法声明* → *函数头* *函数名称* *泛型参数子句*_?_ *函数签名* *泛型约束子句*_?_ -### Protocol Initializer Declaration +### 协议构造器声明 -Protocols declare that conforming types must implement an initializer -by including a protocol initializer declaration in the body of the protocol declaration. -Protocol initializer declarations have the same form as -initializer declarations, except they don't include the initializer's body. -A conforming type can satisfy a nonfailable protocol initializer requirement -by implementing a nonfailable initializer or an `init!` failable initializer. -A conforming type can satisfy a failable protocol initializer requirement -by implementing any kind of initializer. +协议通过在协议声明的主体中包含协议构造器声明,要求符合的类型必须实现一个构造器。协议构造器声明的形式与构造器声明相同,只是不包括构造器的主体。 -When a class implements an initializer to satisfy a protocol's initializer requirement, -the initializer must be marked with the `required` declaration modifier -if the class isn't already marked with the `final` declaration modifier. +一个符合类型可以通过实现一个非可失败的构造器或一个 `init!` 可失败的构造器来满足非可失败协议构造器的要求。一个符合类型可以通过实现任何类型的构造器来满足可失败协议构造器的要求。 -See also . +当一个类实现一个构造器以满足协议的构造器要求时,如果该类尚未标记为 `final` 声明修饰符,则构造器必须标记为 `required` 声明修饰符。 -> Grammar of a protocol initializer declaration: +另见 。 + +> 协议构造器声明的语法: > -> *protocol-initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* *throws-clause*_?_ *generic-where-clause*_?_ \ -> *protocol-initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`rethrows`** *generic-where-clause*_?_ +> *协议构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* *抛出子句*_?_ *泛型约束子句*_?_\ +> *协议构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`重新抛出`** *泛型约束子句*_?_ ### Protocol Subscript Declaration From 72991e124444e2dd3f5e58430740ddb53627e068 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 15:20:12 +0800 Subject: [PATCH 35/67] wip: Protocol Subscript Declaration --- .../ReferenceManual/Declarations.md | 90 ++----------------- 1 file changed, 8 insertions(+), 82 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 9d800179..71507e74 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1881,99 +1881,25 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 > *协议构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* *抛出子句*_?_ *泛型约束子句*_?_\ > *协议构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`重新抛出`** *泛型约束子句*_?_ -### Protocol Subscript Declaration +### 协议下标声明 -Protocols declare that conforming types must implement a subscript -by including a protocol subscript declaration in the body of the protocol declaration. -Protocol subscript declarations have a special form of a subscript declaration: +协议声明符合的类型必须通过在协议声明的主体中包含协议下标声明来实现下标。协议下标声明具有下标声明的特殊形式: ```swift subscript (<#parameters#>) -> <#return type#> { get set } ``` -Subscript declarations only declare the minimum getter and setter implementation -requirements for types that conform to the protocol. -If the subscript declaration includes both the `get` and `set` keywords, -a conforming type must implement both a getter and a setter clause. -If the subscript declaration includes only the `get` keyword, -a conforming type must implement *at least* a getter clause -and optionally can implement a setter clause. -To declare a static subscript requirement in a protocol declaration, -mark the subscript declaration with the `static` declaration modifier. -Structures and enumerations that conform to the protocol -declare the subscript with the `static` keyword, -and classes that conform to the protocol -declare the subscript with either the `static` or `class` keyword. -Extensions that add protocol conformance to a structure, enumeration, or class -use the same keyword as the type they extend uses. -Extensions that provide a default implementation for a static subscript requirement -use the `static` keyword. - -See also . - -> Grammar of a protocol subscript declaration: -> -> *protocol-subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-keyword-block* - -### Protocol Associated Type Declaration - -Protocols declare associated types using the `associatedtype` keyword. -An associated type provides an alias for a type -that's used as part of a protocol's declaration. -Associated types are similar to type parameters in generic parameter clauses, -but they're associated with `Self` in the protocol in which they're declared. -In that context, `Self` refers to the eventual type that conforms to the protocol. -For more information and examples, -see . +下标声明仅声明符合协议的类型所需的最小 getter 和 setter 实现要求。如果下标声明同时包含 `get` 和 `set` 关键字,则符合的类型必须实现 getter 和 setter 子句。如果下标声明仅包含 `get` 关键字,则符合的类型必须实现*至少*一个 getter 子句,并且可以选择性地实现一个 setter 子句。 -You use a generic `where` clause in a protocol declaration -to add constraints to an associated types inherited from another protocol, -without redeclaring the associated types. -For example, the declarations of `SubProtocol` below are equivalent: +在协议声明中声明静态下标要求时,使用 `static` 声明修饰符标记下标声明。符合该协议的结构体和枚举使用 `static` 关键字声明下标,而符合该协议的类则使用 `static` 或 `class` 关键字声明下标。为结构体、枚举或类添加协议符合性的扩展使用与其扩展的类型相同的关键字。为静态下标要求提供默认实现的扩展使用 `static` 关键字。 -```swift -protocol SomeProtocol { - associatedtype SomeType -} - -protocol SubProtocolA: SomeProtocol { - // This syntax produces a warning. - associatedtype SomeType: Equatable -} - -// This syntax is preferred. -protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } -``` - - +> 协议下标声明的语法: +> +> *协议下标声明* → *下标头* *下标结果* *通用条件子句*_?_ *gettersetter关键字块* - + + -See also . +另见 。 -> Grammar of a protocol associated type declaration: +> 协议关联类型声明的语法: > -> *protocol-associated-type-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`associatedtype`** *typealias-name* *type-inheritance-clause*_?_ *typealias-assignment*_?_ *generic-where-clause*_?_ - -## Initializer Declaration +> *协议关联类型声明* → *属性*_?_ *访问级别修饰符*_?_ **`关联类型`** *类型别名名称* *类型继承子句*_?_ *类型别名赋值*_?_ *泛型约束子句*_?_ -An *initializer declaration* introduces an initializer for a class, -structure, or enumeration into your program. -Initializer declarations are declared using the `init` keyword and have -two basic forms. Structure, enumeration, and class types can have any number of initializers, but the rules and associated behavior for class initializers are different. From c390d81222dedd8fe488c10913c5adbebbe11591 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 16:11:04 +0800 Subject: [PATCH 37/67] wip: Initializer Declaration --- .../ReferenceManual/Declarations.md | 127 +++--------------- 1 file changed, 18 insertions(+), 109 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 08e992ac..e04c8839 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2020,138 +2020,47 @@ protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } > > *协议关联类型声明* → *属性*_?_ *访问级别修饰符*_?_ **`关联类型`** *类型别名名称* *类型继承子句*_?_ *类型别名赋值*_?_ *泛型约束子句*_?_ +## 构造器声明 -Structure, enumeration, and class types can have any number of initializers, -but the rules and associated behavior for class initializers are different. -Unlike structures and enumerations, classes have two kinds of initializers: -designated initializers and convenience initializers, -as described in . +一个*构造器声明*在您的程序中引入了一个类、结构或枚举的构造器。构造器声明使用 `init` 关键字声明,并有两种基本形式。 -The following form declares initializers for structures, enumerations, -and designated initializers of classes: +结构、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,如 (doc:Initialization)中所述。 + +以下形式声明了结构体、枚举和类的指定构造器的构造器: ```swift init(<#parameters#>) { - <#statements#> + <#statements#> } ``` -A designated initializer of a class initializes -all of the class's properties directly. It can't call any other initializers -of the same class, and if the class has a superclass, it must call one of -the superclass's designated initializers. -If the class inherits any properties from its superclass, one of the -superclass's designated initializers must be called before any of these -properties can be set or modified in the current class. +类的指定构造器直接初始化类的所有属性。它不能调用同一类的其他构造器,如果该类有一个超类,则必须调用超类的一个指定构造器。如果该类从其超类继承了任何属性,则在当前类中设置或修改这些属性之前,必须调用超类的一个指定构造器。 -Designated initializers can be declared in the context of a class declaration only -and therefore can't be added to a class using an extension declaration. +只能在类声明的上下文中声明,因此不能通过扩展声明添加到类中。 -Initializers in structures and enumerations can call other declared initializers -to delegate part or all of the initialization process. +结构体和枚举中的构造器可以调用其他已声明的构造器,以委托部分或全部初始化过程。 -To declare convenience initializers for a class, -mark the initializer declaration with the `convenience` declaration modifier. +要为一个类声明便利构造器,请使用 `convenience` 声明修饰符标记构造器声明。 ```swift convenience init(<#parameters#>) { - <#statements#> + <#statements#> } ``` -Convenience initializers can delegate the initialization process to another -convenience initializer or to one of the class's designated initializers. -That said, the initialization processes must end with a call to a designated -initializer that ultimately initializes the class's properties. -Convenience initializers can't call a superclass's initializers. - -You can mark designated and convenience initializers with the `required` -declaration modifier to require that every subclass implement the initializer. -A subclass’s implementation of that initializer -must also be marked with the `required` declaration modifier. - -By default, initializers declared in a superclass -aren't inherited by subclasses. -That said, if a subclass initializes all of its stored properties with default values -and doesn't define any initializers of its own, -it inherits all of the superclass's initializers. -If the subclass overrides all of the superclass’s designated initializers, -it inherits the superclass’s convenience initializers. - -As with methods, properties, and subscripts, -you need to mark overridden designated initializers with the `override` declaration modifier. +便利构造器可以将初始化过程委托给另一个便利构造器或类的某个指定构造器。也就是说,初始化过程必须以调用一个指定构造器结束,该构造器最终初始化类的属性。便利构造器不能调用超类的构造器。 -> Note: If you mark an initializer with the `required` declaration modifier, -> you don't also mark the initializer with the `override` modifier -> when you override the required initializer in a subclass. +您可以使用 `required` 声明修饰符标记指定和便利构造器,以要求每个子类实现该构造器。子类对该构造器的实现也必须标记为 `required` 声明修饰符。 -Just like functions and methods, initializers can throw or rethrow errors. -And just like functions and methods, -you use the `throws` or `rethrows` keyword after an initializer's parameters -to indicate the appropriate behavior. -Likewise, initializers can be asynchronous, -and you use the `async` keyword to indicate this. +默认情况下,超类中声明的构造器不会被子类继承。也就是说,如果子类用默认值初始化了所有存储属性,并且没有定义自己的构造器,它将继承超类的所有构造器。如果子类重写了超类的所有指定构造器,它将继承超类的便利构造器。 -To see examples of initializers in various type declarations, -see . +与方法、属性和下标一样,您需要使用 `override` 声明修饰符标记重写的指定构造器。 -### Failable Initializers +> 注意:如果您使用 `required` 声明修饰符标记了一个构造器,则在子类中重写所需的构造器时,不要同时使用 `override` 修饰符标记该构造器。 -A *failable initializer* is a type of initializer that produces an optional instance -or an implicitly unwrapped optional instance of the type the initializer is declared on. -As a result, a failable initializer can return `nil` to indicate that initialization failed. - -To declare a failable initializer that produces an optional instance, -append a question mark to the `init` keyword in the initializer declaration (`init?`). -To declare a failable initializer that produces an implicitly unwrapped optional instance, -append an exclamation point instead (`init!`). The example below shows an `init?` -failable initializer that produces an optional instance of a structure. - -```swift -struct SomeStruct { - let property: String - // produces an optional instance of 'SomeStruct' - init?(input: String) { - if input.isEmpty { - // discard 'self' and return 'nil' - return nil - } - property = input - } -} -``` +就像函数和方法一样,构造器可以抛出或重新抛出错误。与函数和方法一样,您在构造器的参数后使用 `throws` 或 `rethrows` 关键字来指示适当的行为。同样,构造器可以是异步的,您使用 `async` 关键字来指示这一点。 - - -You call an `init?` failable initializer in the same way that you call a nonfailable initializer, -except that you must deal with the optionality of the result. - -```swift -if let actualInstance = SomeStruct(input: "Hello") { - // do something with the instance of 'SomeStruct' -} else { - // initialization of 'SomeStruct' failed and the initializer returned 'nil' -} -``` - - + +调用 init? 可失败的初始化器与调用不可失败的初始化器的方式相同,只是你必须处理结果的可选性。 + +```swift +if let actualInstance = SomeStruct(input: "Hello") { + // do something with the instance of 'SomeStruct' +} else { + // initialization of 'SomeStruct' failed and the initializer returned 'nil' +} +``` + + -A failable initializer can return `nil` -at any point in the implementation of the initializer's body. +可失败的构造器可以在构造器主体的实现中的任何时刻返回`nil`。 -A failable initializer can delegate to any kind of initializer. -A nonfailable initializer can delegate to another nonfailable initializer -or to an `init!` failable initializer. -A nonfailable initializer can delegate to an `init?` failable initializer -by force-unwrapping the result of the superclass's initializer --- -for example, by writing `super.init()!`. +可失败的构造器可以委托给任何类型的构造器。不可失败的构造器可以委托给另一个不可失败的构造器或一个 `init!` 可失败的构造器。不可失败的构造器可以通过强制解包超类构造器的结果来委托给一个 `init?` 可失败的构造器——例如,通过写 `super.init()!`。 -Initialization failure propagates through initializer delegation. -Specifically, -if a failable initializer delegates to an initializer that fails and returns `nil`, -then the initializer that delegated also fails and implicitly returns `nil`. -If a nonfailable initializer delegates to an `init!` failable initializer that fails and returns `nil`, -then a runtime error is raised -(as if you used the `!` operator to unwrap an optional that has a `nil` value). +初始化失败会通过构造器委托传播。具体来说,如果一个可失败的构造器委托给一个失败并返回 `nil` 的构造器,那么委托的构造器也会失败并隐式返回 `nil`。如果一个不可失败的构造器委托给一个失败并返回 `nil` 的 `init!` 可失败构造器,那么会引发运行时错误(就像你使用`!`运算符来解包一个值为 `nil`的可选值一样)。 -A failable designated initializer can be overridden in a subclass -by any kind of designated initializer. -A nonfailable designated initializer can be overridden in a subclass -by a nonfailable designated initializer only. +一个可失败的指定构造器可以在子类中被任何类型的指定构造器重写。一个不可失败的指定构造器只能在子类中被不可失败的指定构造器重写。 -For more information and to see examples of failable initializers, -see . +有关更多信息以及可失败构造器的示例,请参见 。 -> Grammar of an initializer declaration: +> 初始化声明的语法: > -> *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ *throws-clause*_?_ *generic-where-clause*_?_ *initializer-body* \ -> *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ **`rethrows`** *generic-where-clause*_?_ *initializer-body* \ -> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** \ -> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** **`?`** \ -> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** **`!`** \ -> *initializer-body* → *code-block* - -## Deinitializer Declaration - -A *deinitializer declaration* declares a deinitializer for a class type. -Deinitializers take no parameters and have the following form: +> *构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`异步`**_?_ *抛出子句*_?_ *泛型约束子句*_?_ *构造器主体* \ +> *构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`异步`**_?_ **`重新抛出`** *泛型约束子句*_?_ *构造器主体* \ +> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** \ +> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** **`?`** \ +> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** **`!`** \ +> *构造器主体* → *代码块* ```swift deinit { From ddb5d91c70749e30268fca7b12e749458f6af69b Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 22:52:42 +0800 Subject: [PATCH 39/67] wip: Deinitializer Declaration --- .../ReferenceManual/Declarations.md | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 9dced5c5..41c0359a 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2024,7 +2024,7 @@ protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } 一个*构造器声明*在您的程序中引入了一个类、结构或枚举的构造器。构造器声明使用 `init` 关键字声明,并有两种基本形式。 -结构、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,如 (doc:Initialization)中所述。 +结构体、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,如 中所述。 以下形式声明了结构体、枚举和类的指定构造器的构造器: @@ -2066,8 +2066,7 @@ convenience init(<#parameters#>) { 一个*可失败的构造器*是一种构造器,它生成一个可选实例或一个隐式解包的可选实例,具体取决于构造器声明的类型。因此,可失败的构造器可以返回 `nil` 以表示初始化失败。 -To declare a failable initializer that produces an optional instance, append a question mark to the `init` keyword in the initializer declaration (`init?`). To declare a failable initializer that produces an implicitly unwrapped optional instance, append an exclamation point instead (`init!`). The example below shows an `init?` failable initializer that produces an optional instance of a structure. -要声明一个可以失败的构造器,该构造器生成一个可选实例,请在构造器声明中的 `init` 关键字后附加一个问号(`init?`)。要声明一个可以失败的构造器,该构造器生成一个隐式解包的可选实例,请改为附加一个感叹号(`init!`)。下面的示例显示了一个 `init?` 可以失败的构造器,它生成一个结构的可选实例。 +要声明一个可失败的初始化器并生成一个可选实例,需要在初始化器声明中的 init 关键字后面加上问号(`init?`)。要声明一个可失败的初始化器并生成一个隐式解包的可选实例,则需要加上感叹号(`init!`)。下面的示例展示了一个 `init?` 可失败的初始化器,它生成了一个结构体的可选实例。 ```swift struct SomeStruct { @@ -2143,31 +2142,27 @@ if let actualInstance = SomeStruct(input: "Hello") { > *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** **`!`** \ > *构造器主体* → *代码块* +## 析构器声明 + +*析构器声明*为类类型声明一个析构器。析构器不接受参数,具有以下形式: + ```swift deinit { - <#statements#> + <#statements#> } ``` -A deinitializer is called automatically when there are no longer any references -to a class object, just before the class object is deallocated. -A deinitializer can be declared only in the body of a class declaration --- -but not in an extension of a class --- -and each class can have at most one. +析构器在一个类对象不再有任何引用时,会在该对象被释放之前自动调用。析构器只能在类声明的主体内声明,不能在类的扩展中声明,并且每个类最多只能有一个析构器 -A subclass inherits its superclass's deinitializer, -which is implicitly called just before the subclass object is deallocated. -The subclass object isn't deallocated until all deinitializers in its inheritance chain -have finished executing. +子类继承其超类的析构器,该析构器在子类对象被释放之前隐式调用。子类对象在其继承链中的所有析构器执行完毕之前不会被释放。 -Deinitializers aren't called directly. +析构器不会被直接调用。 -For an example of how to use a deinitializer in a class declaration, -see . +在类声明中如何使用析构器的示例,请参见 。 -> Grammar of a deinitializer declaration: +> 析构器声明的语法: > -> *deinitializer-declaration* → *attributes*_?_ **`deinit`** *code-block* +> *析构器声明* → *属性*_?_ **`deinit`** *代码块* ## Extension Declaration From 49c3a1cfc59248ad4f12982387b95964477069f0 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:00:07 +0800 Subject: [PATCH 40/67] wip: Extension Declaration --- .../ReferenceManual/Declarations.md | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 41c0359a..2d0d42a8 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2164,61 +2164,35 @@ deinit { > > *析构器声明* → *属性*_?_ **`deinit`** *代码块* -## Extension Declaration +## 扩展声明 -An *extension declaration* allows you to extend -the behavior of existing types. -Extension declarations are declared using the `extension` keyword -and have the following form: +*扩展声明*允许您扩展现有类型的行为。扩展声明使用 `extension` 关键字声明,具有以下形式: ```swift extension <#type name#> where <#requirements#> { - <#declarations#> + <#declarations#> } ``` -The body of an extension declaration contains zero or more *declarations*. -These *declarations* can include computed properties, computed type properties, -instance methods, type methods, initializers, subscript declarations, -and even class, structure, and enumeration declarations. -Extension declarations can't contain deinitializer or protocol declarations, -stored properties, property observers, or other extension declarations. -Declarations in a protocol extension can't be marked `final`. -For a discussion and several examples of extensions that include various kinds of declarations, -see . +扩展声明的主体包含零个或多个*声明*。这些*声明*可以包括计算属性、计算类型属性、实例方法、类型方法、构造器、下标声明,甚至类、结构体和枚举声明。扩展声明不能包含析构器或协议声明、存储属性、属性观察者或其他扩展声明。协议扩展中的声明不能标记为 `final`。有关包含各种类型声明的扩展的讨论和多个示例,请参见 。 -If the *type name* is a class, structure, or enumeration type, -the extension extends that type. -If the *type name* is a protocol type, -the extension extends all types that conform to that protocol. +如果*类型名称*是类、结构体或枚举类型,则扩展该类型。如果*类型名称*是协议类型,则扩展所有符合该协议的类型。 -Extension declarations that extend a generic type -or a protocol with associated types -can include *requirements*. -If an instance of the extended type -or of a type that conforms to the extended protocol -satisfies the *requirements*, -the instance gains the behavior specified in the declaration. +扩展声明可以扩展具有关联类型的泛型类型或协议,并可以包含*要求*。如果扩展类型的实例或遵循扩展协议的类型的实例满足*要求*,则该实例获得声明中指定的行为。 -Extension declarations can contain initializer declarations. That said, -if the type you're extending is defined in another module, -an initializer declaration must delegate to an initializer already defined in that module -to ensure members of that type are properly initialized. +扩展声明可以包含构造器声明。也就是说,如果您正在扩展的类型在另一个模块中定义,则构造器声明必须委托给该模块中已定义的构造器,以确保该类型的成员得到正确初始化。 -Properties, methods, and initializers of an existing type -can't be overridden in an extension of that type. +现有类型的属性、方法和构造器不能在该类型的扩展中被重写。 -Extension declarations can add protocol conformance to an existing -class, structure, or enumeration type by specifying *adopted protocols*: +扩展声明可以通过指定*采用的协议*,为现有的类、结构体或枚举类型添加协议符合性: ```swift extension <#type name#>: <#adopted protocols#> where <#requirements#> { - <#declarations#> + <#declarations#> } ``` -Extension declarations can't add class inheritance to an existing class, -and therefore you can specify only a list of protocols after the *type name* and colon. +扩展声明不能为现有类添加类继承,因此您只能在*类型名称*和冒号后指定协议列表。 ### Conditional Conformance From b0b873513e5164d987ed9c1e0cf771f0f910099c Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:01:28 +0800 Subject: [PATCH 41/67] wip: Conditional Conformance --- swift-6-beta.docc/ReferenceManual/Declarations.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2d0d42a8..d53ecb0a 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2194,14 +2194,9 @@ extension <#type name#>: <#adopted protocols#> where <#requirements#> { 扩展声明不能为现有类添加类继承,因此您只能在*类型名称*和冒号后指定协议列表。 -### Conditional Conformance - -You can extend a generic type -to conditionally conform to a protocol, -so that instances of the type conform to the protocol -only when certain requirements are met. -You add conditional conformance to a protocol -by including *requirements* in an extension declaration. +### 条件遵循 + +您可以扩展一个泛型类型以有条件地遵循一个协议,从而使该类型的实例仅在满足某些要求时遵循该协议。您通过在扩展声明中包含*要求*来添加对协议的条件遵循。 #### Overridden Requirements Aren't Used in Some Generic Contexts From 552e849635ac20efb894ae17aa1c6632a33b4519 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:16:30 +0800 Subject: [PATCH 42/67] wip: Overridden Requirements Aren't Used in Some Generic Contexts --- .../ReferenceManual/Declarations.md | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index d53ecb0a..306a8cc5 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2198,15 +2198,9 @@ extension <#type name#>: <#adopted protocols#> where <#requirements#> { 您可以扩展一个泛型类型以有条件地遵循一个协议,从而使该类型的实例仅在满足某些要求时遵循该协议。您通过在扩展声明中包含*要求*来添加对协议的条件遵循。 -#### Overridden Requirements Aren't Used in Some Generic Contexts +#### 重写的要求在某些泛型上下文中不会被使用 -In some generic contexts, -types that get behavior from conditional conformance to a protocol -don't always use the specialized implementations -of that protocol's requirements. -To illustrate this behavior, -the following example defines two protocols -and a generic type that conditionally conforms to both protocols. +在某些泛型上下文中,通过条件遵循协议而获得行为的类型,并不总是使用该协议要求的特定实现。为了说明这种行为,以下示例定义了两个协议和一个有条件地遵循这两个协议的泛型类型。 -The `Pair` structure conforms to `Loggable` and `TitledLoggable` -whenever its generic type conforms to `Loggable` or `TitledLoggable`, respectively. -In the example below, -`oneAndTwo` is an instance of `Pair`, -which conforms to `TitledLoggable` -because `String` conforms to `TitledLoggable`. -When the `log()` method is called on `oneAndTwo` directly, -the specialized version containing the title string is used. +`Pair` 结构在其泛型类型分别遵循 `Loggable` 或 `TitledLoggable` 时,也会相应地遵循 `Loggable` 和 `TitledLoggable`。在下面的示例中,`oneAndTwo` 是 `Pair` 的一个实例,由于 `String` 遵循 `TitledLoggable`,因此 `oneAndTwo` 也遵循 `TitledLoggable`。当直接调用 `oneAndTwo` 的 `log()` 方法时,将使用包含标题字符串的特定版本。 ```swift let oneAndTwo = Pair(first: "one", second: "two") @@ -2325,13 +2312,7 @@ oneAndTwo.log() ``` --> -However, when `oneAndTwo` is used in a generic context -or as an instance of the `Loggable` protocol, -the specialized version isn't used. -Swift picks which implementation of `log()` to call -by consulting only the minimum requirements that `Pair` needs to conform to `Loggable`. -For this reason, -the default implementation provided by the `Loggable` protocol is used instead. +然而,当在泛型上下文中使用 `oneAndTwo` 或将其作为 `Loggable` 协议的一个实例时,特定的实现版本不会被使用。`Swift` 在选择调用哪个 `log()` 实现时,只参考 `Pair` 遵循 `Loggable` 所需的最低要求。因此,使用的是 `Loggable` 协议提供的默认实现。 ```swift func doSomething(with x: T) { @@ -2353,8 +2334,7 @@ doSomething(with: oneAndTwo) ``` --> -When `log()` is called on the instance that's passed to `doSomething(_:)`, -the customized title is omitted from the logged string. +当在传递给 `doSomething(_:)` 的实例上调用 `log()` 时,自定义标题会从日志字符串中省略。 ### Protocol Conformance Must Not Be Redundant From 5f65ecf3478fe4a76e389f716a30791ee81a6469 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:19:33 +0800 Subject: [PATCH 43/67] wip: Protocol Conformance Must Not Be Redundant --- swift-6-beta.docc/ReferenceManual/Declarations.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 306a8cc5..3cea8062 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2336,18 +2336,9 @@ doSomething(with: oneAndTwo) 当在传递给 `doSomething(_:)` 的实例上调用 `log()` 时,自定义标题会从日志字符串中省略。 -### Protocol Conformance Must Not Be Redundant - -A concrete type can conform to a particular protocol only once. -Swift marks redundant protocol conformances as an error. -You're likely to encounter this kind of error -in two kinds of situations. -The first situation is when -you explicitly conform to the same protocol multiple times, -but with different requirements. -The second situation is when -you implicitly inherit from the same protocol multiple times. -These situations are discussed in the sections below. +### 协议的遵循不应冗余 + +具体类型只能遵从某个协议一次。Swift 会将多余的协议遵从标记为错误。你可能会在两种情况下遇到这种错误。第一种情况是,当你以不同的要求多次显式地遵从同一个协议。第二种情况是,当你多次隐式地继承同一个协议。以下部分将讨论这些情况。 #### Resolving Explicit Redundancy From a2f742bec21209159ee643ebc965d57033e6b657 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:31:45 +0800 Subject: [PATCH 44/67] wip: Resolving Explicit Redundancy --- swift-6-beta.docc/ReferenceManual/Declarations.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 3cea8062..5922a181 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2340,16 +2340,9 @@ doSomething(with: oneAndTwo) 具体类型只能遵从某个协议一次。Swift 会将多余的协议遵从标记为错误。你可能会在两种情况下遇到这种错误。第一种情况是,当你以不同的要求多次显式地遵从同一个协议。第二种情况是,当你多次隐式地继承同一个协议。以下部分将讨论这些情况。 -#### Resolving Explicit Redundancy +#### 解决显式冗余 -Multiple extensions on a concrete type -can't add conformance to the same protocol, -even if the extensions' requirements are mutually exclusive. -This restriction is demonstrated in the example below. -Two extension declarations attempt to add conditional conformance -to the `Serializable` protocol, -one for arrays with `Int` elements, -and one for arrays with `String` elements. +对一个具体类型的多个扩展不能添加对同一协议的遵循,即使这些扩展的要求是互斥的。以下示例展示了这一限制。两个扩展声明试图为 `Serializable` 协议添加条件遵循,一个是针对包含 `Int` 元素的数组,另一个是针对包含 `String` 元素的数组。 ```swift protocol Serializable { @@ -2399,9 +2392,7 @@ extension Array: Serializable where Element == String { ``` --> -If you need to add conditional conformance based on multiple concrete types, -create a new protocol that each type can conform to -and use that protocol as the requirement when declaring conditional conformance. +如果您需要根据多个具体类型添加条件遵循,请创建一个每个类型都可以遵循的新协议,并在声明条件遵循时使用该协议作为要求。 ```swift protocol SerializableInArray { } From da94a6724e9ec979c8191a0aa3267a2e869435cd Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:39:09 +0800 Subject: [PATCH 45/67] wip: Resolving Implicit Redundancy --- .../ReferenceManual/Declarations.md | 40 +++++-------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 5922a181..2e87f7fd 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2424,22 +2424,13 @@ extension Array: Serializable where Element: SerializableInArray { ``` --> -#### Resolving Implicit Redundancy +#### 解决隐式冗余 -When a concrete type conditionally conforms to a protocol, -that type implicitly conforms to any parent protocols -with the same requirements. +当一个具体类型有条件地遵循一个协议时,该类型隐式地遵循任何具有相同要求的父协议。 -If you need a type to conditionally conform to two protocols -that inherit from a single parent, -explicitly declare conformance to the parent protocol. -This avoids implicitly conforming to the parent protocol twice -with different requirements. +如果您需要一个类型有条件地遵循两个继承自单一父协议的协议,请明确声明对父协议的遵循。这可以避免以不同的要求隐式地两次遵循父协议。 -The following example explicitly declares -the conditional conformance of `Array` to `Loggable` -to avoid a conflict when declaring its conditional conformance -to both `TitledLoggable` and the new `MarkedLoggable` protocol. +以下示例明确声明了`Array`对`Loggable`的条件遵循,以避免在声明其对`TitledLoggable`和新的`MarkedLoggable`协议的条件遵循时发生冲突。 ```swift protocol MarkedLoggable: Loggable { @@ -2487,10 +2478,7 @@ extension Array: MarkedLoggable where Element: MarkedLoggable { } ``` --> -Without the extension -to explicitly declare conditional conformance to `Loggable`, -the other `Array` extensions would implicitly create these declarations, -resulting in an error: +在没有扩展明确声明对 `Loggable` 的条件遵循时,其他 `Array` 扩展会隐式创建这些声明,从而导致错误: ```swift extension Array: Loggable where Element: TitledLoggable { } @@ -2579,21 +2567,13 @@ extension Array: Loggable where Element: MarkedLoggable { } ``` --> -> Grammar of an extension declaration: +> 扩展声明的语法: > -> *extension-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`extension`** *type-identifier* *type-inheritance-clause*_?_ *generic-where-clause*_?_ *extension-body* \ -> *extension-body* → **`{`** *extension-members*_?_ **`}`** +> *扩展声明* → *属性*_?_ *访问级别修饰符*_?_ **`扩展`** *类型标识符* *类型继承条款*_?_ *泛型约束条款*_?_ *扩展主体* \ +> *扩展主体* → **`{`** *扩展成员*_?_ **`}`** > -> *extension-members* → *extension-member* *extension-members*_?_ \ -> *extension-member* → *declaration* | *compiler-control-statement* - -## Subscript Declaration - -A *subscript* declaration allows you to add subscripting support for objects -of a particular type and are typically used to provide a convenient syntax -for accessing the elements in a collection, list, or sequence. -Subscript declarations are declared using the `subscript` keyword -and have the following form: +> *扩展成员* → *扩展成员* *扩展成员*_?_ \ +> *扩展成员* → *声明* | *编译器控制语句* ```swift subscript (<#parameters#>) -> <#return type#> { From 86e2d6288c0eda960b32daecfd32c11e81588f46 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:46:45 +0800 Subject: [PATCH 46/67] wip: Subscript Declaration --- .../ReferenceManual/Declarations.md | 74 +++++++------------ 1 file changed, 25 insertions(+), 49 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 2e87f7fd..c9dd0b7d 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2575,60 +2575,36 @@ extension Array: Loggable where Element: MarkedLoggable { } > *扩展成员* → *扩展成员* *扩展成员*_?_ \ > *扩展成员* → *声明* | *编译器控制语句* +## 下标声明 + +*下标*声明允许您为特定类型的对象添加下标支持,通常用于提供一种方便的语法来访问集合、列表或序列中的元素。下标声明使用 `subscript` 关键字声明,具有以下形式: + ```swift subscript (<#parameters#>) -> <#return type#> { - get { - <#statements#> - } - set(<#setter name#>) { - <#statements#> - } + get { + <#statements#> + } + set(<#setter name#>) { + <#statements#> + } } ``` -Subscript declarations can appear only in the context of a class, structure, -enumeration, extension, or protocol declaration. - -The *parameters* specify one or more indexes used to access elements of the corresponding type -in a subscript expression (for example, the `i` in the expression `object[i]`). -Although the indexes used to access the elements can be of any type, -each parameter must include a type annotation to specify the type of each index. -The *return type* specifies the type of the element being accessed. - -As with computed properties, -subscript declarations support reading and writing the value of the accessed elements. -The getter is used to read the value, -and the setter is used to write the value. -The setter clause is optional, -and when only a getter is needed, you can omit both clauses and simply -return the requested value directly. -That said, if you provide a setter clause, you must also provide a getter clause. - -The *setter name* and enclosing parentheses are optional. -If you provide a setter name, it's used as the name of the parameter to the setter. -If you don't provide a setter name, the default parameter name to the setter is `value`. -The type of the parameter to the setter is the same as the *return type*. - -You can overload a subscript declaration in the type in which it's declared, -as long as the *parameters* or the *return type* differ from the one you're overloading. -You can also override a subscript declaration inherited from a superclass. When you do so, -you must mark the overridden subscript declaration with the `override` declaration modifier. - -Subscript parameters follow the same rules as function parameters, -with two exceptions. -By default, the parameters used in subscripting don't have argument labels, -unlike functions, methods, and initializers. -However, you can provide explicit argument labels -using the same syntax that functions, methods, and initializers use. -In addition, subscripts can't have in-out parameters. -A subscript parameter can have a default value, -using the syntax described in . - -You can also declare subscripts in the context of a protocol declaration, -as described in . - -For more information about subscripting and to see examples of subscript declarations, -see . +下标声明只能出现在类、结构体、枚举、扩展或协议声明的上下文中。 + +*参数*指定了在下标表达式中用于访问对应类型元素的一个或多个索引(例如,在表达式 `object[i]` 中的 `i`)。尽管用于访问元素的索引可以是任意类型,但每个参数都必须包含一个类型注释,以指定每个索引的类型。*返回类型*指定了被访问元素的类型。 + +与计算属性一样,下标声明支持读取和写入所访问元素的值。getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter 时,可以省略两个子句,直接返回请求的值。也就是说,如果提供了 setter 子句,则必须同时提供 getter 子句。 + +*setter 名称*和括号是可选的。如果您提供了 setter 名称,它将用作 setter 的参数名称。如果您不提供 setter 名称,setter 的默认参数名称是 `value`。setter 的参数类型与*返回类型* 同。 + +您可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与您正在重载的不同。您还可以覆盖从超类继承的下标声明。当您这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 + +下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,使用在 中描述的语法。 + +您还可以在协议声明的上下文中声明下标,如 中所述。 + +有关下标的更多信息以及下标声明的示例,请参见 。 ### Type Subscript Declarations From ac13ed51fecbd0c64a7aeaa9c66e3dcc96223fa7 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Tue, 27 Aug 2024 23:52:03 +0800 Subject: [PATCH 47/67] wip: Type Subscript Declarations --- .../ReferenceManual/Declarations.md | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index c9dd0b7d..18a3b508 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2606,16 +2606,9 @@ subscript (<#parameters#>) -> <#return type#> { 有关下标的更多信息以及下标声明的示例,请参见 。 -### Type Subscript Declarations +### 类型下标声明 -To declare a subscript that's exposed by the type, -rather than by instances of the type, -mark the subscript declaration with the `static` declaration modifier. -Classes can mark type computed properties with the `class` declaration modifier instead -to allow subclasses to override the superclass’s implementation. -In a class declaration, -the `static` keyword has the same effect as marking the declaration -with both the `class` and `final` declaration modifiers. +要声明由类型本身而非类型实例公开的下标,可以在下标声明中使用 `static` 声明修饰符。类可以使用 `class` 声明修饰符来标记类型计算属性,以允许子类重写超类的实现。在类声明中,`static` 关键字的效果与将声明标记为 `class` 和 `final` 声明修饰符相同。 > Grammar of a subscript declaration: +> 下标声明的语法: > -> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *code-block* \ -> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-block* \ -> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-keyword-block* \ -> *subscript-head* → *attributes*_?_ *declaration-modifiers*_?_ **`subscript`** *generic-parameter-clause*_?_ *parameter-clause* \ -> *subscript-result* → **`->`** *attributes*_?_ *type* +> *下标声明* → *下标头* *下标结果* *通用 where 子句*_?_ *代码块* \ +> *下标声明* → *下标头* *下标结果* *通用条件子句*_?_ *getter-setter块* \ +> *下标声明* → *下标头* *下标结果* *通用 where 子句*_?_ *getter-setter-关键字-块* \ +> *下标头* → *属性*_?_ *声明修饰符*_?_ **`下标`** *泛型参数子句*_?_ *参数子句* \ +> *下标结果* → **`->`** *属性*_?_ *类型* ## Macro Declaration From b097d6a6fb34a8bd1bca307e4925aa2bd3faaadc Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 28 Aug 2024 00:00:05 +0800 Subject: [PATCH 48/67] wip: Macro Declaration --- .../ReferenceManual/Declarations.md | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 18a3b508..b3a5eeca 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2634,39 +2634,29 @@ subscript (<#parameters#>) -> <#return type#> { > *下标头* → *属性*_?_ *声明修饰符*_?_ **`下标`** *泛型参数子句*_?_ *参数子句* \ > *下标结果* → **`->`** *属性*_?_ *类型* -## Macro Declaration +## 宏声明 -A *macro declaration* introduces a new macro. -It begins with the `macro` keyword -and has the following form: +一个*宏声明*引入一个新的宏。它以 `macro` 关键字开始,具有以下形式: ```swift macro <#name#> = <#macro implementation#> ``` -The *macro implementation* is another macro, -and indicates the location of the code that performs this macro's expansion. -The code that performs macro expansion is a separate Swift program, -that uses the [SwiftSyntax][] module to interact with Swift code. -Call the `externalMacro(module:type:)` macro from the Swift standard library, -passing in the name of a type that contains the macro's implementation, -and the name of the module that contains that type. +*宏实现*是另一个宏,用于指示执行此宏扩展的代码位置。执行宏扩展的代码是一个独立的 Swift 程序,该程序使用 [SwiftSyntax][] 模块与 Swift 代码进行交互。调用 Swift 标准库中的 `externalMacro(module:type:)` 宏,并传入包含宏实现的类型名称以及包含该类型的模块名称。 [SwiftSyntax]: http://github.com/apple/swift-syntax/ -Macros can be overloaded, -following the same model used by functions. -A macro declaration appears only at file scope. +宏可以被重载,遵循与函数相同的模型。宏声明仅在文件作用域内出现。 -For an overview of macros in Swift, see . +有关 Swift 中宏的概述,请参见 。 -> Grammar of a macro declaration: +> 宏声明的语法: > -> *macro-declaration* → *macro-head* *identifier* *generic-parameter-clause*_?_ *macro-signature* *macro-definition*_?_ *generic-where-clause* \ -> *macro-head* → *attributes*_?_ *declaration-modifiers*_?_ **`macro`** \ -> *macro-signature* → *parameter-clause* *macro-function-signature-result*_?_ \ -> *macro-function-signature-result* → **`->`** *type* \ -> *macro-definition* → **`=`** *expression* +> *宏声明* → *宏头* *标识符* *泛型参数子句*_?_ *宏签名* *宏定义*_?_ *泛型约束子句* \ +> *宏头* → *属性*_?_ *声明修饰符*_?_ **`宏`** \ +> *宏签名* → *参数子句* *宏函数签名结果*_?_ \ +> *宏函数签名结果* → **`->`** *类型* \ +> *宏定义* → **`=`** *表达式* ## Operator Declaration From 23a6b80b25cd4c7a3a5c4d2280617486763bceb9 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 28 Aug 2024 10:57:31 +0800 Subject: [PATCH 49/67] wip: Operator Declaration --- .../ReferenceManual/Declarations.md | 70 ++++++------------- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index b3a5eeca..948461f3 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2658,84 +2658,56 @@ macro <#name#> = <#macro implementation#> > *宏函数签名结果* → **`->`** *类型* \ > *宏定义* → **`=`** *表达式* -## Operator Declaration +## 操作符声明 -An *operator declaration* introduces a new infix, prefix, -or postfix operator into your program -and is declared using the `operator` keyword. +*运算符声明*将新的中缀、前缀或后缀运算符引入到您的程序中,并使用 `operator` 关键字进行声明。 -You can declare operators of three different fixities: -infix, prefix, and postfix. -The *fixity* of an operator specifies the relative position of an operator -to its operands. +您可以声明三种不同优先级的运算符:中缀、前缀和后缀。运算符的*优先级*指定了运算符相对于其操作数的相对位置。 -There are three basic forms of an operator declaration, -one for each fixity. -The fixity of the operator is specified by marking the operator declaration with the -`infix`, `prefix`, or `postfix` declaration modifier before the `operator` keyword. -In each form, the name of the operator can contain only the operator characters -defined in . +运算符声明有三种基本形式,每种形式对应一种结合性(fixity)。运算符的结合性通过在 `operator` 关键字之前标注 `infix`、`prefix` 或 `postfix` 声明修饰符来指定。在每种形式中,运算符的名称只能包含 中定义的运算符字符。 -The following form declares a new infix operator: +以下形式声明了一个新的中缀运算符: ```swift infix operator <#operator name#>: <#precedence group#> ``` -An *infix operator* is a binary operator that's written between its two operands, -such as the familiar addition operator (`+`) in the expression `1 + 2`. +An *infix operator* is a binary operator that's written between its two operands, such as the familiar addition operator (`+`) in the expression `1 + 2`. +一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式`1 + 2`中熟悉的加法运算符`+`。 -Infix operators can optionally specify a precedence group. -If you omit the precedence group for an operator, -Swift uses the default precedence group, `DefaultPrecedence`, -which specifies a precedence just higher than `TernaryPrecedence`. -For more information, see . +中缀运算符可以选择性地指定优先级组。如果您省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 -The following form declares a new prefix operator: +以下形式声明了一个新的前缀运算符: ```swift prefix operator <#operator name#> ``` -A *prefix operator* is a unary operator that's written immediately before its operand, -such as the prefix logical NOT operator (`!`) in the expression `!a`. +*前缀运算符* 是一种一元运算符,它直接写在操作数之前,例如表达式 `!a` 中的前缀逻辑非运算符(`!`)。 -Prefix operators declarations don't specify a precedence level. -Prefix operators are nonassociative. +前缀运算符声明不指定优先级。前缀运算符是非结合的。 -The following form declares a new postfix operator: +以下形式声明了一个新的后缀运算符: ```swift postfix operator <#operator name#> ``` -A *postfix operator* is a unary operator that's written immediately after its operand, -such as the postfix forced-unwrap operator (`!`) in the expression `a!`. +*后缀运算符*是一种一元运算符,它紧跟在操作数后面,例如在表达式 `a!` 中的后缀强制解包运算符 `!`。 -As with prefix operators, postfix operator declarations don't specify a precedence level. -Postfix operators are nonassociative. +与前缀运算符一样,后缀运算符声明不指定优先级。后缀运算符是非结合的。 -After declaring a new operator, -you implement it by declaring a static method that has the same name as the operator. -The static method is a member of -one of the types whose values the operator takes as an argument --- -for example, an operator that multiplies a `Double` by an `Int` -is implemented as a static method on either the `Double` or `Int` structure. -If you're implementing a prefix or postfix operator, -you must also mark that method declaration with the corresponding `prefix` or `postfix` -declaration modifier. -To see an example of how to create and implement a new operator, -see . +声明新运算符后,可以通过声明一个与运算符同名的静态方法来实现它。这个静态方法是运算符参数之一的类型的成员——例如,一个将 `Double` 与 `Int` 相乘的运算符可以在 `Double` 或 `Int` 结构上实现为静态方法。如果你要实现一个前缀或后缀运算符,还必须在方法声明中添加相应的 `prefix` 或 `postfix` 声明修饰符。要查看如何创建和实现新运算符的示例,请参阅 。 -> Grammar of an operator declaration: +> 操作符声明的语法: > -> *operator-declaration* → *prefix-operator-declaration* | *postfix-operator-declaration* | *infix-operator-declaration* +> *运算符声明* → *前缀运算符声明* | *后缀运算符声明* | *中缀运算符声明* > -> *prefix-operator-declaration* → **`prefix`** **`operator`** *operator* \ -> *postfix-operator-declaration* → **`postfix`** **`operator`** *operator* \ -> *infix-operator-declaration* → **`infix`** **`operator`** *operator* *infix-operator-group*_?_ +> *前缀运算符声明* → **`前缀`** **`运算符`** *运算符* \ +> *后缀运算符声明* → **`后缀`** **`运算符`** *运算符* \ +> *中缀运算符声明* → **`中缀`** **`运算符`** *运算符* *中缀运算符组*_?_ > -> *infix-operator-group* → **`:`** *precedence-group-name* +> *中缀运算符组* → **`:`** *优先级组名称* ## Precedence Group Declaration From 8cd1f6b7cfd8496efd4371e07b03a717479849e7 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 28 Aug 2024 11:10:32 +0800 Subject: [PATCH 50/67] wip: Precedence Group Declaration --- .../ReferenceManual/Declarations.md | 103 +++++------------- 1 file changed, 27 insertions(+), 76 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 948461f3..ff6c0920 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2709,14 +2709,11 @@ postfix operator <#operator name#> > > *中缀运算符组* → **`:`** *优先级组名称* -## Precedence Group Declaration +## 优先级组声明 -A *precedence group declaration* introduces -a new grouping for infix operator precedence into your program. -The precedence of an operator specifies how tightly the operator -binds to its operands, in the absence of grouping parentheses. +*优先级组声明*在程序中引入了一个新的中缀运算符优先级分组。运算符的优先级指定了在没有分组括号的情况下,运算符与其操作数的绑定紧密程度。 -A precedence group declaration has the following form: +优先级组声明具有以下形式: ```swift precedencegroup <#precedence group name#> { @@ -2727,82 +2724,36 @@ precedencegroup <#precedence group name#> { } ``` -The *lower group names* and *higher group names* lists specify -the new precedence group's relation to existing precedence groups. -The `lowerThan` precedence group attribute may only be used -to refer to precedence groups declared outside of the current module. -When two operators compete with each other for their operands, -such as in the expression `2 + 3 * 5`, -the operator with the higher relative precedence -binds more tightly to its operands. - -> Note: Precedence groups related to each other -> using *lower group names* and *higher group names* -> must fit into a single relational hierarchy, -> but they *don't* have to form a linear hierarchy. -> This means it's possible to have precedence groups -> with undefined relative precedence. -> Operators from those precedence groups -> can't be used next to each other without grouping parentheses. - -Swift defines numerous precedence groups to go along -with the operators provided by the Swift standard library. -For example, the addition (`+`) and subtraction (`-`) operators -belong to the `AdditionPrecedence` group, -and the multiplication (`*`) and division (`/`) operators -belong to the `MultiplicationPrecedence` group. -For a complete list of precedence groups -provided by the Swift standard library, -see [Operator Declarations](https://developer.apple.com/documentation/swift/operator_declarations). - -The *associativity* of an operator specifies how a sequence of operators -with the same precedence level are grouped together in the absence of grouping parentheses. -You specify the associativity of an operator by writing -one of the context-sensitive keywords `left`, `right`, or `none` --- -if your omit the associativity, the default is `none`. -Operators that are left-associative group left-to-right. -For example, -the subtraction operator (`-`) is left-associative, -so the expression `4 - 5 - 6` is grouped as `(4 - 5) - 6` -and evaluates to `-7`. -Operators that are right-associative group right-to-left, -and operators that are specified with an associativity of `none` -don't associate at all. -Nonassociative operators of the same precedence level -can't appear adjacent to each to other. -For example, -the `<` operator has an associativity of `none`, -which means `1 < 2 < 3` isn't a valid expression. - -The *assignment* of a precedence group specifies the precedence of an operator -when used in an operation that includes optional chaining. -When set to `true`, an operator in the corresponding precedence group -uses the same grouping rules during optional chaining -as the assignment operators from the Swift standard library. -Otherwise, when set to `false` or omitted, -operators in the precedence group follows the same optional chaining rules -as operators that don't perform assignment. - -> Grammar of a precedence group declaration: +*低级组名称*和*高级组名称*列表指定了新优先级组与现有优先级组的关系。`lowerThan` 优先级组属性只能用于引用当前模块外声明的优先级组。当两个运算符争夺其操作数时,如在表达式 `2 + 3 * 5` 中,具有较高相对优先级的运算符会更紧密地绑定到其操作数上。 + +> 注意:使用*低级组名称*和*高级组名称*相关联的优先级组必须适合于单一的关系层次结构,但它们*不*必形成线性层次结构。这意味着可以有相对优先级未定义的优先级组。来自这些优先级组的运算符不能在没有分组括号的情况下相互使用。 + +Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator*declarations)。 + +运算符的*结合性*指定了在没有分组括号的情况下,具有相同优先级的运算符序列是如何分组的。通过写入上下文敏感的关键字之一来指定运算符的结合性:`left`、`right` 或 `none` ——如果您省略结合性,默认值为 `none`。左结合的运算符从左到右分组。例如,减法运算符(`-`)是左结合的,因此表达式`4 - 5 - 6` 被分组为 `(4 - 5) - 6`,并计算为 `-7`。右结合的运算符从右到左分组,而指定为 `none` 的运算符则完全不结合。相同优先级的非结合运算符不能相邻出现。例如,`<` 运算符的结合性为 `none`,这意味着 `1 < 2 < 3` 不是一个有效的表达式。 + +*赋值*优先级组的设置指定了运算符在包含可选链操作中的优先级。当设置为 `true` 时,对应优先级组中的运算符在可选链操作期间使用与 Swift 标准库中的赋值运算符相同的分组规则。否则,当设置为 `false` 或省略时,该优先级组中的运算符将遵循与不执行赋值的运算符相同的可选链规则。 + +> 优先级组声明的语法: > -> *precedence-group-declaration* → **`precedencegroup`** *precedence-group-name* **`{`** *precedence-group-attributes*_?_ **`}`** +> *优先级组声明* → **`precedencegroup`** *优先级组名称* **`{`** *优先级组属性*_?_ **`}`** > -> *precedence-group-attributes* → *precedence-group-attribute* *precedence-group-attributes*_?_ \ -> *precedence-group-attribute* → *precedence-group-relation* \ -> *precedence-group-attribute* → *precedence-group-assignment* \ -> *precedence-group-attribute* → *precedence-group-associativity* +> *优先级组属性* → *优先级组属性* *优先级组属性*_?_ \ +> *优先级组属性* → *优先级组关系* \ +> *优先级组属性* → *优先级组分配* \ +> *优先级组属性* → *优先级组结合性* > -> *precedence-group-relation* → **`higherThan`** **`:`** *precedence-group-names* \ -> *precedence-group-relation* → **`lowerThan`** **`:`** *precedence-group-names* +> *优先级组关系* → **`高于`** **`:`** *优先级组名称* \ +> *优先级组关系* → **`低于`** **`:`** *优先级组名称* > -> *precedence-group-assignment* → **`assignment`** **`:`** *boolean-literal* +> *优先级组分配* → **`分配`** **`:`** *布尔字面量* > -> *precedence-group-associativity* → **`associativity`** **`:`** **`left`** \ -> *precedence-group-associativity* → **`associativity`** **`:`** **`right`** \ -> *precedence-group-associativity* → **`associativity`** **`:`** **`none`** +> *优先级组结合性* → **`结合性`** **`:`** **`左`** \ +> *优先级组结合性* → **`结合性`** **`:`** **`右`** \ +> *优先级组关联性* → **`关联性`** **`:`** **`无`** > -> *precedence-group-names* → *precedence-group-name* | *precedence-group-name* **`,`** *precedence-group-names* \ -> *precedence-group-name* → *identifier* +> *优先级组名称* → *优先级组名称* | *优先级组名称* **`,`** *优先级组名称* +> *优先级组名称* → *标识符* ## Declaration Modifiers From 674b5776bca03c5240e51df2fd6d032c83bd6d4d Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 30 Aug 2024 12:38:31 +0800 Subject: [PATCH 51/67] wip: Declaration Modifiers --- .../ReferenceManual/Declarations.md | 130 +++--------------- 1 file changed, 18 insertions(+), 112 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index ff6c0920..74d64040 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2755,58 +2755,23 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 > *优先级组名称* → *优先级组名称* | *优先级组名称* **`,`** *优先级组名称* > *优先级组名称* → *标识符* -## Declaration Modifiers - -*Declaration modifiers* are keywords or context-sensitive keywords that modify the behavior -or meaning of a declaration. You specify a declaration modifier by writing the appropriate -keyword or context-sensitive keyword between a declaration's attributes (if any) and the keyword -that introduces the declaration. - -- term `class`: - Apply this modifier to a member of a class - to indicate that the member is a member of the class itself, - rather than a member of instances of the class. - Members of a superclass that have this modifier - and don't have the `final` modifier - can be overridden by subclasses. - -- term `dynamic`: - Apply this modifier to any member of a class that can be represented by Objective-C. - When you mark a member declaration with the `dynamic` modifier, - access to that member is always dynamically dispatched using the Objective-C runtime. - Access to that member is never inlined or devirtualized by the compiler. - - Because declarations marked with the `dynamic` modifier are dispatched - using the Objective-C runtime, they must be marked with the - `objc` attribute. - -- term `final`: - Apply this modifier to a class or to a property, method, - or subscript member of a class. It's applied to a class to indicate that the class - can't be subclassed. It's applied to a property, method, or subscript of a class - to indicate that a class member can't be overridden in any subclass. - For an example of how to use the `final` attribute, - see . - -- term `lazy`: - Apply this modifier to a stored variable property of a class or structure - to indicate that the property's initial value is calculated and stored at most - once, when the property is first accessed. - For an example of how to use the `lazy` modifier, - see . - -- term `optional`: - Apply this modifier to a protocol's property, method, - or subscript members to indicate that a conforming type isn't required - to implement those members. - - You can apply the `optional` modifier only to protocols that are marked - with the `objc` attribute. As a result, only class types can adopt and conform - to a protocol that contains optional member requirements. - For more information about how to use the `optional` modifier - and for guidance about how to access optional protocol members --- - for example, when you're not sure whether a conforming type implements them --- - see . +## 声明修饰符 + +*声明修饰符* 是修饰声明行为或含义的关键字或上下文敏感关键字。你可以通过在声明的属性(如果有的话)和引入声明的关键字之间,写上适当的关键字或上下文敏感关键字来指定声明修饰符。 + +- `class`:将此修饰符应用于类的成员,以指示该成员是类本身的成员,而不是类实例的成员。具有此修饰符且没有 `final` 修饰符的超类成员可以被子类重写。 + +- `dynamic`:将此修饰符应用于可以用 Objective-C 表示的类的任何成员。当您使用 `dynamic` 修饰符标记成员声明时,对该成员的访问始终通过 Objective-C 运行时动态分派。对该成员的访问永远不会被编译器内联或去虚拟化。 + +因为带有 `dynamic` 修饰符的声明是通过 Objective-C 运行时进行调度的,因此它们必须标记为 `objc` 属性。 + +- `final`:将此修饰符应用于类或类的属性、方法或下标成员。它应用于类以指示该类不能被子类化。它应用于类的属性、方法或下标,以指示类成员在任何子类中不能被重写。有关如何使用 `final` 属性的示例,请参见 。 + +- `lazy`:将此修饰符应用于类或结构体的存储变量属性,以指示该属性的初始值在第一次访问该属性时最多计算并存储一次。有关如何使用 `lazy` 修饰符的示例,请参见 。 + +- `optional`:将此修饰符应用于协议的属性、方法或下标成员,表示实现该协议的类型不必实现这些成员。 + +你只能将 `optional` 修饰符应用于带有 `objc` 属性的协议。因此,只有类类型可以采用并遵循包含可选成员要求的协议。有关如何使用 `optional` 修饰符的更多信息,以及在不确定遵循类型是否实现了这些成员时如何访问可选协议成员的指导,请参见 -- term `required`: - Apply this modifier to a designated or convenience initializer - of a class to indicate that every subclass must implement that initializer. - The subclass's implementation of that initializer - must also be marked with the `required` modifier. - -- term `static`: - Apply this modifier to a member of a structure, class, enumeration, or protocol - to indicate that the member is a member of the type, - rather than a member of instances of that type. - In the scope of a class declaration, - writing the `static` modifier on a member declaration - has the same effect as writing the `class` and `final` modifiers - on that member declaration. - However, constant type properties of a class are an exception: - `static` has its normal, nonclass meaning there - because you can't write `class` or `final` on those declarations. - -- term `unowned`: - Apply this modifier to a stored variable, constant, or stored property - to indicate that the variable or property has an unowned reference - to the object stored as its value. - If you try to access the variable or property - after the object has been deallocated, - a runtime error is raised. - Like a weak reference, - the type of the property or value must be a class type; - unlike a weak reference, - the type is non-optional. - For an example and more information about the `unowned` modifier, - see . - -- term `unowned(safe)`: - An explicit spelling of `unowned`. - -- term `unowned(unsafe)`: - Apply this modifier to a stored variable, constant, or stored property - to indicate that the variable or property has an unowned reference - to the object stored as its value. - If you try to access the variable or property - after the object has been deallocated, - you'll access the memory at the location where the object used to be, - which is a memory-unsafe operation. - Like a weak reference, - the type of the property or value must be a class type; - unlike a weak reference, - the type is non-optional. - For an example and more information about the `unowned` modifier, - see . - -- term `weak`: - Apply this modifier to a stored variable or stored variable property - to indicate that the variable or property has a weak reference to the - object stored as its value. The type of the variable or property - must be an optional class type. - If you access the variable or property - after the object has been deallocated, - its value is `nil`. - For an example and more information about the `weak` modifier, - see . +- `required`:将此修饰符应用于类的指定或便利构造器,以指示每个子类必须实现该构造器。子类对该构造器的实现也必须标记为 `required` 修饰符。 ### Access Control Levels From 590f628e14ab6ff69a208b622d71fe6427f96ad2 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 30 Aug 2024 12:57:07 +0800 Subject: [PATCH 52/67] wip: Access Control Levels --- .../ReferenceManual/Declarations.md | 115 +++++++----------- 1 file changed, 41 insertions(+), 74 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 74d64040..b8a8c4f7 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2783,77 +2783,44 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 - `required`:将此修饰符应用于类的指定或便利构造器,以指示每个子类必须实现该构造器。子类对该构造器的实现也必须标记为 `required` 修饰符。 -### Access Control Levels - -Swift provides five levels of access control: open, public, internal, file private, and private. -You can mark a declaration with one of the access-level modifiers below -to specify the declaration's access level. -Access control is discussed in detail in . - -- term `open`: - Apply this modifier to a declaration to indicate the declaration can be accessed and subclassed - by code in the same module as the declaration. - Declarations marked with the `open` access-level modifier can also be accessed and subclassed - by code in a module that imports the module that contains that declaration. - -- term `public`: - Apply this modifier to a declaration to indicate the declaration can be accessed and subclassed - by code in the same module as the declaration. - Declarations marked with the `public` access-level modifier can also be accessed (but not subclassed) - by code in a module that imports the module that contains that declaration. - -- term `package`: - Apply this modifier to a declaration - to indicate that the declaration can be accessed - only by code in the same package as the declaration. - A package is a unit of code distribution - that you define in the build system you're using. - When the build system compiles code, - it specifies the package name - by passing the `-package-name` flag to the Swift compiler. - Two modules are part of the same package - if the build system specifies the same package name when building them. - -- term `internal`: - Apply this modifier to a declaration to indicate the declaration can be accessed - only by code in the same module as the declaration. - By default, - most declarations are implicitly marked with the `internal` access-level modifier. - -- term `fileprivate`: - Apply this modifier to a declaration to indicate the declaration can be accessed - only by code in the same source file as the declaration. - -- term `private`: - Apply this modifier to a declaration to indicate the declaration can be accessed - only by code within the declaration's immediate enclosing scope. - -For the purpose of access control, -extensions behave as follows: - -- If there are multiple extensions in the same file, - and those extensions all extend the same type, - then all of those extensions have the same access-control scope. - The extensions and the type they extend can be in different files. - -- If there are extensions in the same file as the type they extend, - the extensions have the same access-control scope as the type they extend. - -- Private members declared in a type's declaration - can be accessed from extensions to that type. - Private members declared in one extension - can be accessed from other extensions - and from the extended type's declaration. - -Each access-level modifier above optionally accepts a single argument, -which consists of the `set` keyword enclosed in parentheses --- -for example, `private(set)`. -Use this form of an access-level modifier when you want to specify an access level -for the setter of a variable or subscript that's less than or equal -to the access level of the variable or subscript itself, -as discussed in . - -> Grammar of a declaration modifier: +- `static`:将此修饰符应用于结构体、类、枚举或协议的成员,以指示该成员属于类型本身,而不是该类型实例的成员。在类声明的范围内,将 `static` 修饰符应用于成员声明上,与在该成员声明上写 `class` 和 `final` 修饰符具有相同的效果。然而,类的常量类型属性是一个例外:在这种情况下,`static` 具有其通常的、非类相关的含义,因为在这些声明上不能使用 `class` 或 `final`。 + +- `unowned`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,将会引发运行时错误。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 + +- `unowned(safe)`:`unowned` 的明确拼写。 + +- `unowned(unsafe)`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,您将访问对象曾经所在位置的内存,这是一种不安全的内存操作。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,该类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 + +- `weak`:将此修饰符应用于存储变量或存储变量属性,以指示该变量或属性对作为其值存储的对象具有弱引用。变量或属性的类型必须是可选类类型。如果在对象被释放后访问该变量或属性,其值为 `nil`。有关 `weak` 修饰符的示例和更多信息,请参见 。 + + +### 访问控制级别 + +Swift 提供五种访问控制级别:open、public、internal、file private 和 private。您可以使用以下访问级别修饰符之一标记声明,以指定声明的访问级别。访问控制的详细信息请参见 。 + +- `open`:将此修饰符应用于声明,以指示该声明可以被与该声明位于同一模块中的代码访问和子类化。标记为 `open` 访问级别修饰符的声明也可以被导入包含该声明的模块的模块中的代码访问和子类化。 + +- `public`:将此修饰符应用于声明,以指示该声明可以被与该声明位于同一模块中的代码访问和子类化。标记为 `public` 访问级别修饰符的声明也可以被导入包含该声明的模块的模块中的代码访问(但不能被子类化)。 + +- `package`:将此修饰符应用于声明,以指示该声明只能被与声明在同一包中的代码访问。包是您在使用的构建系统中定义的代码分发单元。当构建系统编译代码时,它通过将 `-package-name` 标志传递给 Swift 编译器来指定包名称。如果构建系统在构建它们时指定相同的包名称,则两个模块属于同一个包。 + +- `internal`:将此修饰符应用于声明,以指示该声明只能被与声明在同一模块中的代码访问。默认情况下,大多数声明隐式标记为 `internal` 访问级别修饰符。 + +- `fileprivate`:将此修饰符应用于声明,以指示该声明只能被与声明在同一源文件中的代码访问。 + +- `private`:将此修饰符应用于声明,以指示该声明只能被声明的直接封闭范围内的代码访问。 + +出于访问控制的目的,扩展的行为如下: + +- 如果同一个文件中有多个扩展,并且这些扩展都扩展了相同的类型,那么所有这些扩展具有相同的访问控制范围。这些扩展和它们扩展的类型可以在不同的文件中。 + +- 如果扩展与其扩展的类型在同一文件中,则扩展具有与其扩展的类型相同的访问控制范围。 + +- 在类型声明中声明的私有成员可以从该类型的扩展中访问。在一个扩展中声明的私有成员可以从其他扩展和扩展类型的声明中访问。 + +每个上述访问级别修饰符可选择性地接受一个参数,该参数由括号中包含的 `set` 关键字组成——例如,`private(set)`。当您想要为变量或下标的setter指定一个小于或等于变量或下标本身的访问级别时,请使用这种形式的访问级别修饰符,如 中所讨论的。 + +> 声明修饰语的语法: > > *declaration-modifier* → **`class`** | **`convenience`** | **`dynamic`** | **`final`** | **`infix`** | **`lazy`** | **`optional`** | **`override`** | **`postfix`** | **`prefix`** | **`required`** | **`static`** | **`unowned`** | **`unowned`** **`(`** **`safe`** **`)`** | **`unowned`** **`(`** **`unsafe`** **`)`** | **`weak`** \ > *declaration-modifier* → *access-level-modifier* \ @@ -2872,11 +2839,11 @@ as discussed in . > > *actor-isolation-modifier* → **`nonisolated`** -> Beta Software: +> Beta 软件: > -> This documentation contains preliminary information about an API or technology in development. This information is subject to change, and software implemented according to this documentation should be tested with final operating system software. +> 本文件包含有关正在开发的 API 或技术的初步信息。此信息可能会更改,按照本文件实施的软件应与最终操作系统软件进行测试。 > -> Learn more about using [Apple's beta software](https://developer.apple.com/support/beta-software/). +> 了解有关使用 [Apple Beta 软件](https://developer.apple.com/support/beta-software/) 的更多信息。 -在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *类型*)是可选的,如中所述。 + +在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,如 中所述。 要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;您不能使用 `class` 或 `final` 声明修饰符来允许或禁止子类重写。类型属性的讨论请参见 。 @@ -173,11 +173,11 @@ print("The second number is \(secondNumber).") > 常量声明的语法: > -> *常量声明* → *属性*_?_ *声明修饰符*_?_ **`let`** *模式构造器列表* +> *constant-declaration* → *attributes*_?_ *declaration-modifiers*_?_ **`let`** *pattern-initializer-list* > -> *模式构造器列表* → *模式构造器* | *模式构造器* **`,`** *模式构造器列表* \ -> *模式构造器* → *模式* *构造器*_?_ \ -> *构造器* → **`=`** *表达式* +> *pattern-initializer-list* → *pattern-initializer* | *pattern-initializer* **`,`** *pattern-initializer-list* \ +> *pattern-initializer* → *pattern* *initializer*_?_ \ +> *initializer* → **`=`** *expression* ## 变量声明 @@ -199,7 +199,7 @@ var <#variable name#>: <#type#> = <#expression#> 您可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种形式的变量声明。当这种形式的变量声明在全局范围或函数的局部范围内声明时,它被称为*存储变量*。当它在类或结构体声明的上下文中声明时,它被称为*存储变量属性*。 -构造器*表达式*不能出现在协议声明中,但在所有其他上下文中,构造器*表达式*是可选的。也就是说,如果没有构造器*表达式*,变量声明必须包含显式类型注释(`:` *类型*)。 +构造器*表达式*不能出现在协议声明中,但在所有其他上下文中,构造器*表达式*是可选的。也就是说,如果没有构造器*表达式*,变量声明必须包含显式类型注释(`:` *type*)。 与常量声明一样,如果变量声明省略了构造器*表达式*,则在第一次读取该变量之前必须为其设置一个值。同样,像常量声明一样,如果*变量名*是一个元组模式,则元组中每个项的名称都绑定到构造器*表达式*中的相应值。 @@ -381,34 +381,32 @@ newAndOld.x = 200 要声明一个类型变量属性,请使用 `static` 声明修饰符标记声明。类可以使用 `class` 声明修饰符标记类型计算属性,以允许子类覆盖超类的实现。类型属性的讨论请参见 。 -> 变量声明的语法: -> -> *变量-声明* → *变量-声明-头* *模式-初始化-列表* \ -> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *代码-块* \ -> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *getter-setter-块* \ -> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *getter-setter-关键字-块* \ -> *变量-声明* → *变量-声明-头* *变量-名* *构造器* *willSet-didSet-块* \ -> *变量-声明* → *变量-声明-头* *变量-名* *类型-注解* *构造器*_?_ *willSet-didSet-块* +> *variable-declaration* → *variable-declaration-head* *pattern-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* *initializer* *willSet-didSet-block* \ +> *variable-declaration* → *variable-declaration-head* *variable-name* *type-annotation* *initializer*_?_ *willSet-didSet-block* > -> *变量-声明-头* → *属性*_?_ *声明-修饰符*_?_ **`var`** \ -> *变量-名* → *标识符* +> *variable-declaration-head* → *attributes*_?_ *declaration-modifiers*_?_ **`var`** \ +> *variable-name* → *identifier* > -> *getter-setter-块* → *代码块* \ -> *getter-setter-块* → **`{`** *getter-子句* *setter-子句*_?_ **`}`** \ -> *getter-setter-块* → **`{`** *setter-子句* *getter-子句* **`}`** \ -> *getter-子句* → *特性*_?_ *可变-修饰符*_?_ **`get`** *代码-块* \ -> *setter-子句* → *特性*_?_ *可变-修饰符*_?_ **`set`** *setter-名称*_?_ *代码-块* \ -> *setter-名称* → **`(`** *标识符* **`)`** +> *getter-setter-block* → *code-block* \ +> *getter-setter-block* → **`{`** *getter-clause* *setter-clause*_?_ **`}`** \ +> *getter-setter-block* → **`{`** *setter-clause* *getter-clause* **`}`** \ +> *getter-clause* → *attributes*_?_ *mutation-modifier*_?_ **`get`** *code-block* \ +> *setter-clause* → *attributes*_?_ *mutation-modifier*_?_ **`set`** *setter-name*_?_ *code-block* \ +> *setter-name* → **`(`** *identifier* **`)`** > -> *getter-setter-关键字-块* → **`{`** *getter-关键字-子句* *setter-关键字-子句*_?_ **`}`** \ -> *getter-setter-关键字-块* → **`{`** *setter-关键字-子句* *getter-关键字-子句* **`}`** \ -> *getter-关键字-子句* → *属性*_?_ *可变-修饰符*_?_ **`get`** \ -> *setter-关键字-子句* → *属性*_?_ *可变-修饰符*_?_ **`set`** +> *getter-setter-keyword-block* → **`{`** *getter-keyword-clause* *setter-keyword-clause*_?_ **`}`** \ +> *getter-setter-keyword-block* → **`{`** *setter-keyword-clause* *getter-keyword-clause* **`}`** \ +> *getter-keyword-clause* → *attributes*_?_ *mutation-modifier*_?_ **`get`** \ +> *setter-keyword-clause* → *attributes*_?_ *mutation-modifier*_?_ **`set`** > -> *willSet-didSet-block* → **`{`** *willSet-子句* *didSet-子句*_?_ **`}`** \ -> *willSet-didSet-block* → **`{`** *didSet-子句* *willSet-子句*_?_ **`}`** \ -> *willSet-子句* → *特性*_?_ **`willSet`** *setter-名称*_?_ *代码-块* \ -> *didSet-子句* → *特性*_?_ **`didSet`** *setter-名称*_?_ *代码-块* +> *willSet-didSet-block* → **`{`** *willSet-clause* *didSet-clause*_?_ **`}`** \ +> *willSet-didSet-block* → **`{`** *didSet-clause* *willSet-clause*_?_ **`}`** \ +> *willSet-clause* → *attributes*_?_ **`willSet`** *setter-name*_?_ *code-block* \ +> *didSet-clause* → *attributes*_?_ **`didSet`** *setter-name*_?_ *code-block* -A closure or nested function that captures an in-out parameter must be nonescaping. If you need to capture an in-out parameter without mutating it, use a capture list to explicitly capture the parameter immutably. 一个捕获输入输出参数的闭包或嵌套函数必须是非逃逸的。如果您需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 ```swift @@ -739,6 +734,7 @@ func someFunction(a: inout Int) -> () -> Int { --> 如果您需要捕获并修改一个 in-out 参数,请使用一个显式的局部副本,例如在多线程代码中,确保所有修改在函数返回之前都已完成。 + ```swift func multithreadedFunction(queue: DispatchQueue, x: inout Int) { // Make a local copy and manually copy it back. @@ -987,7 +983,7 @@ f(7) // Invalid, missing argument label 重写超类方法的方法必须标记为 `override` 声明修饰符。没有 `override` 修饰符而重写方法,或者在不重写超类方法的情况下使用 `override` 修饰符,都是编译时错误。 -与类型相关的方法,而不是与类型实例相关的方法,必须使用 static 声明修饰符来标记(枚举和结构体使用 static,类可以使用 static 或 class 声明修饰符)。用 class 声明修饰符标记的类类型方法可以被子类的实现重写;用 class final 或 static 标记的类类型方法则不能被重写。 +与类型相关的方法,而不是与类型实例相关的方法,必须使用 static 声明修饰符来标记(枚举和结构体使用 `static`,类可以使用 `static` 或 `class` 声明修饰符)。用 `class` 声明修饰符标记的类类型方法可以被子类的实现重写;用 `class final` 或 `static` 标记的类类型方法则不能被重写。 -`subscript(dynamicMember:)` 下标为成员查找提供了语法糖,如 中所述。 +`subscript(dynamicMember:)` 下标为成员查找提供了语法糖,详见 。 ### 抛出函数和方法 @@ -1271,26 +1267,27 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 > 函数声明的语法: > -> *函数声明* → *函数头* *函数名称* *泛型参数子句*_?_ *函数签名* *泛型约束子句*_?_ *函数主体*_?_ +> *function-declaration* → *function-head* *function-name* *generic-parameter-clause*_?_ *function-signature* *generic-where-clause*_?_ *function-body*_?_ > -> *函数头* → *属性*_?_ *声明修饰符*_?_ **`func`** \ -> *函数名* → *标识符* | *运算符* +> *function-head* → *attributes*_?_ *declaration-modifiers*_?_ **`func`** \ +> *function-name* → *identifier* | *operator* > -> *函数签名* → *参数子句* **`异步`**_?_ *抛出子句*_?_ *函数结果*_?_ \ -> *函数签名* → *参数子句* **`async`**_?_ **`rethrows`** *函数结果*_?_ \ -> *函数结果* → **`->`** *属性*_?_ *类型* \ -> *函数体* → *代码块* +> *function-signature* → *parameter-clause* **`async`**_?_ *throws-clause*_?_ *function-result*_?_ \ +> *function-signature* → *parameter-clause* **`async`**_?_ **`rethrows`** *function-result*_?_ \ +> *function-result* → **`->`** *attributes*_?_ *type* \ +> *function-body* → *code-block* > -> *参数子句* → **`(`** **`)`** | **`(`** *参数列表* **`)`** \ -> *参数列表* → *参数* | *参数* **`,`** *参数列表* \ -> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* *默认参数子句*_?_ \ -> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* \ -> *参数* → *外部参数名称*_?_ *本地参数名称* *参数类型注解* **`...`** +> *parameter-clause* → **`(`** **`)`** | **`(`** *parameter-list* **`)`** \ +> *parameter-list* → *parameter* | *parameter* **`,`** *parameter-list* \ +> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* *default-argument-clause*_?_ \ +> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* \ +> *parameter* → *external-parameter-name*_?_ *local-parameter-name* *parameter-type-annotation* **`...`** > -> *外部参数名称* → *标识符* \ -> *局部参数名称* → *标识符* \ -> *参数类型注解* → **`:`** *属性*_?_ *参数修饰符*_?_ *类型* \ -> *参数修饰符* → **`输入输出`** | **`借用`** | **`消耗`** *默认参数子句* → **`=`** *表达式* +> *external-parameter-name* → *identifier* \ +> *local-parameter-name* → *identifier* \ +> *parameter-type-annotation* → **`:`** *attributes*_?_ *parameter-modifier*_?_ *type* \ +> *parameter-modifier* → **`inout`** | **`borrowing`** | **`consuming`** +> *default-argument-clause* → **`=`** *expression* + ```swift enum Tree { case empty @@ -1440,7 +1444,7 @@ enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { } ``` -在这种形式中,每个案例块由`case`关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。与第一种形式中的案例不同,每个案例都有一个基础值,称为*原始值*,其基本类型相同。这些值的类型在*原始值类型*中指定,必须表示整数、浮点数、字符串或单个字符。特别是,*原始值类型*必须符合`Equatable`协议,并且符合以下协议之一:`ExpressibleByIntegerLiteral` 用于整数字面量,`ExpressibleByFloatLiteral` 用于浮点字面量,`ExpressibleByStringLiteral` 用于包含任意数量字符的字符串字面量,以及 `ExpressibleByUnicodeScalarLiteral` 或 `ExpressibleByExtendedGraphemeClusterLiteral` 用于仅包含单个字符的字符串字面量。每个案例必须具有唯一名称并分配唯一的原始值。 +在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。与第一种形式中的案例不同,每个案例都有一个基础值,称为*原始值*,其基本类型相同。这些值的类型在*原始值类型*中指定,必须表示整数、浮点数、字符串或单个字符。特别是,*原始值类型*必须符合 `Equatable` 协议,并且符合以下协议之一:`ExpressibleByIntegerLiteral` 用于整数字面量,`ExpressibleByFloatLiteral` 用于浮点字面量,`ExpressibleByStringLiteral` 用于包含任意数量字符的字符串字面量,以及 `ExpressibleByUnicodeScalarLiteral` 或 `ExpressibleByExtendedGraphemeClusterLiteral` 用于仅包含单个字符的字符串字面量。每个案例必须具有唯一名称并分配唯一的原始值。 -调用 init? 可失败的初始化器与调用不可失败的初始化器的方式相同,只是你必须处理结果的可选性。 +调用 `init?` 可失败的初始化器与调用不可失败的初始化器的方式相同,只是你必须处理结果的可选性。 ```swift if let actualInstance = SomeStruct(input: "Hello") { @@ -2123,7 +2125,7 @@ if let actualInstance = SomeStruct(input: "Hello") { ``` --> -可失败的构造器可以在构造器主体的实现中的任何时刻返回`nil`。 +可失败的构造器可以在构造器主体的实现中的任何时刻返回 `nil`。 可失败的构造器可以委托给任何类型的构造器。不可失败的构造器可以委托给另一个不可失败的构造器或一个 `init!` 可失败的构造器。不可失败的构造器可以通过强制解包超类构造器的结果来委托给一个 `init?` 可失败的构造器——例如,通过写 `super.init()!`。 @@ -2135,12 +2137,12 @@ if let actualInstance = SomeStruct(input: "Hello") { > 初始化声明的语法: > -> *构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`异步`**_?_ *抛出子句*_?_ *泛型约束子句*_?_ *构造器主体* \ -> *构造器声明* → *构造器头* *泛型参数子句*_?_ *参数子句* **`异步`**_?_ **`重新抛出`** *泛型约束子句*_?_ *构造器主体* \ -> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** \ -> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** **`?`** \ -> *初始化头* → *属性*_?_ *声明修饰符*_?_ **`init`** **`!`** \ -> *构造器主体* → *代码块* +> *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ *throws-clause*_?_ *generic-where-clause*_?_ *initializer-body* \ +> *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ **`rethrows`** *generic-where-clause*_?_ *initializer-body* \ +> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** \ +> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** **`?`** \ +> *initializer-head* → *attributes*_?_ *declaration-modifiers*_?_ **`init`** **`!`** \ +> *initializer-body* → *code-block* ## 析构器声明 @@ -2162,7 +2164,7 @@ deinit { > 析构器声明的语法: > -> *析构器声明* → *属性*_?_ **`deinit`** *代码块* +> *deinitializer-declaration* → *attributes*_?_ **`deinit`** *code-block* ## 扩展声明 @@ -2312,7 +2314,7 @@ oneAndTwo.log() ``` --> -然而,当在泛型上下文中使用 `oneAndTwo` 或将其作为 `Loggable` 协议的一个实例时,特定的实现版本不会被使用。`Swift` 在选择调用哪个 `log()` 实现时,只参考 `Pair` 遵循 `Loggable` 所需的最低要求。因此,使用的是 `Loggable` 协议提供的默认实现。 +然而,当在泛型上下文中使用 `oneAndTwo` 或将其作为 `Loggable` 协议的一个实例时,特定的实现版本不会被使用。Swift 在选择调用哪个 `log()` 实现时,只参考 `Pair` 遵循 `Loggable` 所需的最低要求。因此,使用的是 `Loggable` 协议提供的默认实现。 ```swift func doSomething(with x: T) { @@ -2430,7 +2432,7 @@ extension Array: Serializable where Element: SerializableInArray { 如果您需要一个类型有条件地遵循两个继承自单一父协议的协议,请明确声明对父协议的遵循。这可以避免以不同的要求隐式地两次遵循父协议。 -以下示例明确声明了`Array`对`Loggable`的条件遵循,以避免在声明其对`TitledLoggable`和新的`MarkedLoggable`协议的条件遵循时发生冲突。 +以下示例明确声明了 `Array` 对 `Loggable` 的条件遵循,以避免在声明其对 `TitledLoggable` 和新的 `MarkedLoggable` 协议的条件遵循时发生冲突。 ```swift protocol MarkedLoggable: Loggable { @@ -2569,11 +2571,11 @@ extension Array: Loggable where Element: MarkedLoggable { } > 扩展声明的语法: > -> *扩展声明* → *属性*_?_ *访问级别修饰符*_?_ **`扩展`** *类型标识符* *类型继承条款*_?_ *泛型约束条款*_?_ *扩展主体* \ -> *扩展主体* → **`{`** *扩展成员*_?_ **`}`** +> *extension-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`extension`** *type-identifier* *type-inheritance-clause*_?_ *generic-where-clause*_?_ *extension-body* \ +> *extension-body* → **`{`** *extension-members*_?_ **`}`** > -> *扩展成员* → *扩展成员* *扩展成员*_?_ \ -> *扩展成员* → *声明* | *编译器控制语句* +> *extension-members* → *extension-member* *extension-members*_?_ \ +> *extension-member* → *declaration* | *compiler-control-statement* ## 下标声明 @@ -2600,9 +2602,9 @@ subscript (<#parameters#>) -> <#return type#> { 您可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与您正在重载的不同。您还可以覆盖从超类继承的下标声明。当您这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 -下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,使用在 中描述的语法。 +下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,详见 。 -您还可以在协议声明的上下文中声明下标,如 中所述。 +您还可以在协议声明的上下文中声明下标,详见 。 有关下标的更多信息以及下标声明的示例,请参见 。 @@ -2625,14 +2627,13 @@ subscript (<#parameters#>) -> <#return type#> { ``` --> -> Grammar of a subscript declaration: > 下标声明的语法: > -> *下标声明* → *下标头* *下标结果* *通用 where 子句*_?_ *代码块* \ -> *下标声明* → *下标头* *下标结果* *通用条件子句*_?_ *getter-setter块* \ -> *下标声明* → *下标头* *下标结果* *通用 where 子句*_?_ *getter-setter-关键字-块* \ -> *下标头* → *属性*_?_ *声明修饰符*_?_ **`下标`** *泛型参数子句*_?_ *参数子句* \ -> *下标结果* → **`->`** *属性*_?_ *类型* +> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *code-block* \ +> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-block* \ +> *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-keyword-block* \ +> *subscript-head* → *attributes*_?_ *declaration-modifiers*_?_ **`subscript`** *generic-parameter-clause*_?_ *parameter-clause* \ +> *subscript-result* → **`->`** *attributes*_?_ *type* ## 宏声明 @@ -2652,11 +2653,11 @@ macro <#name#> = <#macro implementation#> > 宏声明的语法: > -> *宏声明* → *宏头* *标识符* *泛型参数子句*_?_ *宏签名* *宏定义*_?_ *泛型约束子句* \ -> *宏头* → *属性*_?_ *声明修饰符*_?_ **`宏`** \ -> *宏签名* → *参数子句* *宏函数签名结果*_?_ \ -> *宏函数签名结果* → **`->`** *类型* \ -> *宏定义* → **`=`** *表达式* +> *macro-declaration* → *macro-head* *identifier* *generic-parameter-clause*_?_ *macro-signature* *macro-definition*_?_ *generic-where-clause* \ +> *macro-head* → *attributes*_?_ *declaration-modifiers*_?_ **`macro`** \ +> *macro-signature* → *parameter-clause* *macro-function-signature-result*_?_ \ +> *macro-function-signature-result* → **`->`** *type* \ +> *macro-definition* → **`=`** *expression* ## 操作符声明 @@ -2673,7 +2674,7 @@ infix operator <#operator name#>: <#precedence group#> ``` An *infix operator* is a binary operator that's written between its two operands, such as the familiar addition operator (`+`) in the expression `1 + 2`. -一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式`1 + 2`中熟悉的加法运算符`+`。 +一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式 `1 + 2` 中熟悉的加法运算符`+`。 中缀运算符可以选择性地指定优先级组。如果您省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 @@ -2701,13 +2702,13 @@ postfix operator <#operator name#> > 操作符声明的语法: > -> *运算符声明* → *前缀运算符声明* | *后缀运算符声明* | *中缀运算符声明* +> *operator-declaration* → *prefix-operator-declaration* | *postfix-operator-declaration* | *infix-operator-declaration* > -> *前缀运算符声明* → **`前缀`** **`运算符`** *运算符* \ -> *后缀运算符声明* → **`后缀`** **`运算符`** *运算符* \ -> *中缀运算符声明* → **`中缀`** **`运算符`** *运算符* *中缀运算符组*_?_ +> *prefix-operator-declaration* → **`prefix`** **`operator`** *operator* \ +> *postfix-operator-declaration* → **`postfix`** **`operator`** *operator* \ +> *infix-operator-declaration* → **`infix`** **`operator`** *operator* *infix-operator-group*_?_ > -> *中缀运算符组* → **`:`** *优先级组名称* +> *infix-operator-group* → **`:`** *precedence-group-name* ## 优先级组声明 @@ -2728,7 +2729,7 @@ precedencegroup <#precedence group name#> { > 注意:使用*低级组名称*和*高级组名称*相关联的优先级组必须适合于单一的关系层次结构,但它们*不*必形成线性层次结构。这意味着可以有相对优先级未定义的优先级组。来自这些优先级组的运算符不能在没有分组括号的情况下相互使用。 -Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator*declarations)。 +Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator_declarations)。 运算符的*结合性*指定了在没有分组括号的情况下,具有相同优先级的运算符序列是如何分组的。通过写入上下文敏感的关键字之一来指定运算符的结合性:`left`、`right` 或 `none` ——如果您省略结合性,默认值为 `none`。左结合的运算符从左到右分组。例如,减法运算符(`-`)是左结合的,因此表达式`4 - 5 - 6` 被分组为 `(4 - 5) - 6`,并计算为 `-7`。右结合的运算符从右到左分组,而指定为 `none` 的运算符则完全不结合。相同优先级的非结合运算符不能相邻出现。例如,`<` 运算符的结合性为 `none`,这意味着 `1 < 2 < 3` 不是一个有效的表达式。 @@ -2736,24 +2737,24 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 > 优先级组声明的语法: > -> *优先级组声明* → **`precedencegroup`** *优先级组名称* **`{`** *优先级组属性*_?_ **`}`** +> *precedence-group-declaration* → **`precedencegroup`** *precedence-group-name* **`{`** *precedence-group-attributes*_?_ **`}`** > -> *优先级组属性* → *优先级组属性* *优先级组属性*_?_ \ -> *优先级组属性* → *优先级组关系* \ -> *优先级组属性* → *优先级组分配* \ -> *优先级组属性* → *优先级组结合性* +> *precedence-group-attributes* → *precedence-group-attribute* *precedence-group-attributes*_?_ \ +> *precedence-group-attribute* → *precedence-group-relation* \ +> *precedence-group-attribute* → *precedence-group-assignment* \ +> *precedence-group-attribute* → *precedence-group-associativity* > -> *优先级组关系* → **`高于`** **`:`** *优先级组名称* \ -> *优先级组关系* → **`低于`** **`:`** *优先级组名称* +> *precedence-group-relation* → **`higherThan`** **`:`** *precedence-group-names* \ +> *precedence-group-relation* → **`lowerThan`** **`:`** *precedence-group-names* > -> *优先级组分配* → **`分配`** **`:`** *布尔字面量* +> *precedence-group-assignment* → **`assignment`** **`:`** *boolean-literal* > -> *优先级组结合性* → **`结合性`** **`:`** **`左`** \ -> *优先级组结合性* → **`结合性`** **`:`** **`右`** \ -> *优先级组关联性* → **`关联性`** **`:`** **`无`** +> *precedence-group-associativity* → **`associativity`** **`:`** **`left`** \ +> *precedence-group-associativity* → **`associativity`** **`:`** **`right`** \ +> *precedence-group-associativity* → **`associativity`** **`:`** **`none`** > -> *优先级组名称* → *优先级组名称* | *优先级组名称* **`,`** *优先级组名称* -> *优先级组名称* → *标识符* +> *precedence-group-names* → *precedence-group-name* | *precedence-group-name* **`,`** *precedence-group-names* \ +> *precedence-group-name* → *identifier* ## 声明修饰符 From d1e60d0e063f36369600fd832d574138c624d27f Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 30 Aug 2024 14:30:06 +0800 Subject: [PATCH 54/67] fix: head comment --- swift-6-beta.docc/ReferenceManual/Declarations.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 82ad5435..aef60962 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1,9 +1,3 @@ - - # Declarations 引入类型、运算符、变量以及其他名称和构造。 From d09d183788f8a1135d591ab5b8db3754b950455c Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 30 Aug 2024 14:40:58 +0800 Subject: [PATCH 55/67] fix: blockquotes colon issue --- .../ReferenceManual/Declarations.md | 68 ++++++++++--------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index aef60962..ce844e29 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -6,7 +6,7 @@ 在 Swift 中,大多数声明也是定义,因为它们在声明的同时被实现或初始化。也就是说,由于协议不实现其成员,大多数协议成员仅仅是声明。为了方便起见,并且因为在 Swift 中这种区别并不是那么重要,术语*声明*涵盖了声明和定义。 -> 声明的语法: +> 声明的语法: > > *declaration* → *import-declaration* \ > *declaration* → *constant-declaration* \ @@ -34,7 +34,7 @@ Swift 源文件中的顶级代码由零个或多个语句、声明和表达式 您编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。 -> 顶级声明的语法: +> 顶级声明的语法: > > *top-level-declaration* → *statements*_?_ @@ -57,7 +57,7 @@ Swift 源文件中的顶级代码由零个或多个语句、声明和表达式 TODO: Discuss scope. I assume a code block creates a new scope? --> -> 代码块的语法: +> 代码块的语法: > > *code-block* → **`{`** *statements*_?_ **`}`** @@ -80,7 +80,7 @@ import <#module#>.<#submodule#> TODO: Need to add more to this section. --> -> 导入声明的语法: +> 导入声明的语法: > > *import-declaration* → *attributes*_?_ **`import`** *import-kind*_?_ *import-path* > @@ -99,7 +99,8 @@ let <#constant name#>: <#type#> = <#expression#> 当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要在第一次读取其值之前保证已设置值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器证明在读取之前值已被确定设置。 -> 注意:确定性初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果您可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 +> 注意: +> 确定性初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果您可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 -> 枚举声明的语法: +> 枚举声明的语法: > > *enum-declaration* → *attributes*_?_ *access-level-modifier*_?_ *union-style-enum* \ > *enum-declaration* → *attributes*_?_ *access-level-modifier*_?_ *raw-value-style-enum* @@ -1581,7 +1583,7 @@ struct <#structure name#>: <#adopted protocols#> { 您可以通过扩展声明扩展结构类型的行为,详见 。 -> 结构体声明的语法: +> 结构体声明的语法: > > *struct-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`struct`** *struct-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *struct-body* \ > *struct-name* → *identifier* \ @@ -1632,7 +1634,7 @@ class <#class name#>: <#superclass#>, <#adopted protocols#> { 您可以通过扩展声明扩展类类型的行为,如 中所讨论的。 -> 类声明的语法: +> 类声明的语法: > > *class-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`final`**_?_ **`class`** *class-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *class-body* \ > *class-declaration* → *attributes*_?_ **`final`** *access-level-modifier*_?_ **`class`** *class-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *class-body* \ @@ -1683,7 +1685,7 @@ actor 是引用类型;当分配给变量或常量,或作为参数传递给 whose corresponding parameter is non-escaping and non-Sendable. --> -> actor 声明的语法: +> actor 声明的语法: > > *actor-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`actor`** *actor-name* *generic-parameter-clause*_?_ *type-inheritance-clause*_?_ *generic-where-clause*_?_ *actor-body* \ > *actor-name* → *identifier* \ @@ -1708,7 +1710,8 @@ protocol <#protocol name#>: <#inherited protocols#> { 协议类型可以从任意数量的其他协议继承。当一个协议类型从其他协议继承时,这些其他协议的要求集合会被聚合,任何从当前协议继承的类型必须符合所有这些要求。有关如何使用协议继承的示例,请参见 。 -> 注意:您还可以使用协议组合类型聚合多个协议的合规性要求,详见 。 +> 注意: +> 您还可以使用协议组合类型聚合多个协议的合规性要求,详见 。 您可以通过在该类型的扩展声明中采用协议,为先前声明的类型添加协议符合性。在扩展中,您必须实现所采用协议的所有要求。如果该类型已经实现了所有要求,您可以将扩展声明的主体留空。 @@ -1770,13 +1773,14 @@ protocol SomeProtocol: AnyObject { 任何从标记为 `AnyObject` 要求的协议继承的协议,也只能被类类型采用。 -> 注意:如果一个协议标记了 `objc` 属性,则 `AnyObject` 要求隐式应用于该协议;无需明确将该协议标记为 `AnyObject` 要求。 +> 注意: +> 如果一个协议标记了 `objc` 属性,则 `AnyObject` 要求隐式应用于该协议;无需明确将该协议标记为 `AnyObject` 要求。 协议是命名类型,因此它们可以出现在代码中与其他命名类型相同的位置,如 中所讨论的。然而,您无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 您可以使用协议来声明类或结构体的代理应该实现哪些方法,如 中所述。 -> 协议声明的语法: +> 协议声明的语法: > > *protocol-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`protocol`** *protocol-name* *type-inheritance-clause*_?_ *generic-where-clause*_?_ *protocol-body* \ > *protocol-name* → *identifier* \ @@ -1842,7 +1846,7 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 另见 。 -> 协议属性声明的语法: +> 协议属性声明的语法: > > *protocol-property-declaration* → *variable-declaration-head* *variable-name* *type-annotation* *getter-setter-keyword-block* @@ -1858,7 +1862,7 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 TODO: Talk about using ``Self`` in parameters and return types. --> -> 协议方法声明的语法: +> 协议方法声明的语法: > > *protocol-method-declaration* → *function-head* *function-name* *generic-parameter-clause*_?_ *function-signature* *generic-where-clause*_?_ @@ -1872,7 +1876,7 @@ getter 和 setter 的要求可以通过符合类型以多种方式满足。如 另见 。 -> 协议构造器声明的语法: +> 协议构造器声明的语法: > > *protocol-initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* *throws-clause*_?_ *generic-where-clause*_?_ \ > *protocol-initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`rethrows`** *generic-where-clause*_?_ @@ -1892,7 +1896,7 @@ subscript (<#parameters#>) -> <#return type#> { get set } 另见 。 -> 协议下标声明的语法: +> 协议下标声明的语法: > > *protocol-subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-keyword-block* @@ -2012,7 +2016,7 @@ protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } 另见 。 -> 协议关联类型声明的语法: +> 协议关联类型声明的语法: > > *protocol-associated-type-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`associatedtype`** *typealias-name* *type-inheritance-clause*_?_ *typealias-assignment*_?_ *generic-where-clause*_?_ @@ -2052,7 +2056,8 @@ convenience init(<#parameters#>) { 与方法、属性和下标一样,您需要使用 `override` 声明修饰符标记重写的指定构造器。 -> 注意:如果您使用 `required` 声明修饰符标记了一个构造器,则在子类中重写所需的构造器时,不要同时使用 `override` 修饰符标记该构造器。 +> 注意: +> 如果您使用 `required` 声明修饰符标记了一个构造器,则在子类中重写所需的构造器时,不要同时使用 `override` 修饰符标记该构造器。 就像函数和方法一样,构造器可以抛出或重新抛出错误。与函数和方法一样,您在构造器的参数后使用 `throws` 或 `rethrows` 关键字来指示适当的行为。同样,构造器可以是异步的,您使用 `async` 关键字来指示这一点。 @@ -2129,7 +2134,7 @@ if let actualInstance = SomeStruct(input: "Hello") { 有关更多信息以及可失败构造器的示例,请参见 。 -> 初始化声明的语法: +> 初始化声明的语法: > > *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ *throws-clause*_?_ *generic-where-clause*_?_ *initializer-body* \ > *initializer-declaration* → *initializer-head* *generic-parameter-clause*_?_ *parameter-clause* **`async`**_?_ **`rethrows`** *generic-where-clause*_?_ *initializer-body* \ @@ -2156,7 +2161,7 @@ deinit { 在类声明中如何使用析构器的示例,请参见 。 -> 析构器声明的语法: +> 析构器声明的语法: > > *deinitializer-declaration* → *attributes*_?_ **`deinit`** *code-block* @@ -2563,7 +2568,7 @@ extension Array: Loggable where Element: MarkedLoggable { } ``` --> -> 扩展声明的语法: +> 扩展声明的语法: > > *extension-declaration* → *attributes*_?_ *access-level-modifier*_?_ **`extension`** *type-identifier* *type-inheritance-clause*_?_ *generic-where-clause*_?_ *extension-body* \ > *extension-body* → **`{`** *extension-members*_?_ **`}`** @@ -2621,7 +2626,7 @@ subscript (<#parameters#>) -> <#return type#> { ``` --> -> 下标声明的语法: +> 下标声明的语法: > > *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *code-block* \ > *subscript-declaration* → *subscript-head* *subscript-result* *generic-where-clause*_?_ *getter-setter-block* \ @@ -2645,7 +2650,7 @@ macro <#name#> = <#macro implementation#> 有关 Swift 中宏的概述,请参见 。 -> 宏声明的语法: +> 宏声明的语法: > > *macro-declaration* → *macro-head* *identifier* *generic-parameter-clause*_?_ *macro-signature* *macro-definition*_?_ *generic-where-clause* \ > *macro-head* → *attributes*_?_ *declaration-modifiers*_?_ **`macro`** \ @@ -2694,7 +2699,7 @@ postfix operator <#operator name#> 声明新运算符后,可以通过声明一个与运算符同名的静态方法来实现它。这个静态方法是运算符参数之一的类型的成员——例如,一个将 `Double` 与 `Int` 相乘的运算符可以在 `Double` 或 `Int` 结构上实现为静态方法。如果你要实现一个前缀或后缀运算符,还必须在方法声明中添加相应的 `prefix` 或 `postfix` 声明修饰符。要查看如何创建和实现新运算符的示例,请参阅 。 -> 操作符声明的语法: +> 操作符声明的语法: > > *operator-declaration* → *prefix-operator-declaration* | *postfix-operator-declaration* | *infix-operator-declaration* > @@ -2721,7 +2726,8 @@ precedencegroup <#precedence group name#> { *低级组名称*和*高级组名称*列表指定了新优先级组与现有优先级组的关系。`lowerThan` 优先级组属性只能用于引用当前模块外声明的优先级组。当两个运算符争夺其操作数时,如在表达式 `2 + 3 * 5` 中,具有较高相对优先级的运算符会更紧密地绑定到其操作数上。 -> 注意:使用*低级组名称*和*高级组名称*相关联的优先级组必须适合于单一的关系层次结构,但它们*不*必形成线性层次结构。这意味着可以有相对优先级未定义的优先级组。来自这些优先级组的运算符不能在没有分组括号的情况下相互使用。 +> 注意: +> 使用*低级组名称*和*高级组名称*相关联的优先级组必须适合于单一的关系层次结构,但它们*不*必形成线性层次结构。这意味着可以有相对优先级未定义的优先级组。来自这些优先级组的运算符不能在没有分组括号的情况下相互使用。 Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator_declarations)。 @@ -2729,7 +2735,7 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 *赋值*优先级组的设置指定了运算符在包含可选链操作中的优先级。当设置为 `true` 时,对应优先级组中的运算符在可选链操作期间使用与 Swift 标准库中的赋值运算符相同的分组规则。否则,当设置为 `false` 或省略时,该优先级组中的运算符将遵循与不执行赋值的运算符相同的可选链规则。 -> 优先级组声明的语法: +> 优先级组声明的语法: > > *precedence-group-declaration* → **`precedencegroup`** *precedence-group-name* **`{`** *precedence-group-attributes*_?_ **`}`** > @@ -2815,7 +2821,7 @@ Swift 提供五种访问控制级别:open、public、internal、file private 每个上述访问级别修饰符可选择性地接受一个参数,该参数由括号中包含的 `set` 关键字组成——例如,`private(set)`。当您想要为变量或下标的setter指定一个小于或等于变量或下标本身的访问级别时,请使用这种形式的访问级别修饰符,如 中所讨论的。 -> 声明修饰语的语法: +> 声明修饰语的语法: > > *declaration-modifier* → **`class`** | **`convenience`** | **`dynamic`** | **`final`** | **`infix`** | **`lazy`** | **`optional`** | **`override`** | **`postfix`** | **`prefix`** | **`required`** | **`static`** | **`unowned`** | **`unowned`** **`(`** **`safe`** **`)`** | **`unowned`** **`(`** **`unsafe`** **`)`** | **`weak`** \ > *declaration-modifier* → *access-level-modifier* \ From e8b414c03173810e36200b5972ccdf8ffc6eddaa Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 30 Aug 2024 14:43:49 +0800 Subject: [PATCH 56/67] fix: dash issue --- swift-6-beta.docc/ReferenceManual/Declarations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index ce844e29..dc995d3b 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -819,7 +819,7 @@ func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { } ``` -如果函数需要保持参数的值,例如,通过将其存储在全局变量中 --- 您可以使用 `copy` 明确地复制该值。 +如果函数需要保持参数的值,例如,通过将其存储在全局变量中——您可以使用 `copy` 明确地复制该值。 ```swift // As above, but this `isLessThan` also wants to record the smallest value @@ -1229,7 +1229,7 @@ func <#function name#>(<#parameters#>) async -> <#return type#> { } ``` -对异步函数或方法的调用必须包装在一个 `await` 表达式中 --- 也就是说,它们必须在 `await` 操作符的作用域内。 +对异步函数或方法的调用必须包装在一个 `await` 表达式中——也就是说,它们必须在 `await` 操作符的作用域内。 `async` 关键字是函数类型的一部分,同步函数是异步函数的子类型。因此,您可以覆盖异在期望异步函数的上下文中使用同步函数。例如,您可以用同步方法步方法,并且同步方法可以满足需要异步方法的协议要求。 @@ -1298,7 +1298,7 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 一个*枚举声明*将一个命名的枚举类型引入到你的程序中。 -枚举声明有两种基本形式,并使用 `enum` 关键字进行声明。使用任一形式声明的枚举的主体包含零个或多个值 --- 称为 *枚举案例* --- 以及任意数量的声明,包括计算属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor 声明。枚举声明不能包含析构器或协议声明。 +枚举声明有两种基本形式,并使用 `enum` 关键字进行声明。使用任一形式声明的枚举的主体包含零个或多个值——称为 *枚举案例*——以及任意数量的声明,包括计算属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor 声明。枚举声明不能包含析构器或协议声明。 枚举类型可以采用任意数量的协议,但不能从类、结构或其他枚举继承。 @@ -1396,7 +1396,7 @@ enum Tree { ``` --> -要为所有具有关联值的枚举案例启用间接引用,请使用 `indirect` 修饰符标记整个枚举 --- 当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 +要为所有具有关联值的枚举案例启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 一个标记为 `indirect` 修饰符的枚举可以包含具有关联值的情况和没有关联值的情况的混合。然而,它不能包含任何也标记为 `indirect` 修饰符的案例。 @@ -1715,7 +1715,7 @@ protocol <#protocol name#>: <#inherited protocols#> { 您可以通过在该类型的扩展声明中采用协议,为先前声明的类型添加协议符合性。在扩展中,您必须实现所采用协议的所有要求。如果该类型已经实现了所有要求,您可以将扩展声明的主体留空。 -默认情况下,符合协议的类型必须实现协议中声明的所有属性、方法和下标。也就是说,您可以使用 `optional` 声明修饰符来标记这些协议成员声明,以指定符合类型的实现是可选的。`optional` 修饰符只能应用于标记为 `objc` 属性的成员,并且只能应用于标记为 `objc` 属性的协议成员。因此,只有类类型可以采用并符合包含可选成员要求的协议。有关如何使用 `optional` 声明修饰符的信息,以及如何访问可选协议成员的指导——例如,当您不确定符合类型是否实现它们时 --- 请参见 。 +默认情况下,符合协议的类型必须实现协议中声明的所有属性、方法和下标。也就是说,您可以使用 `optional` 声明修饰符来标记这些协议成员声明,以指定符合类型的实现是可选的。`optional` 修饰符只能应用于标记为 `objc` 属性的成员,并且只能应用于标记为 `objc` 属性的协议成员。因此,只有类类型可以采用并符合包含可选成员要求的协议。有关如何使用 `optional` 声明修饰符的信息,以及如何访问可选协议成员的指导——例如,当您不确定符合类型是否实现它们时——请参见 -在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,如 中所述。 +在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,祥见 。 要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;您不能使用 `class` 或 `final` 声明修饰符来允许或禁止子类重写。类型属性的讨论请参见 。 @@ -181,9 +181,9 @@ print("The second number is \(secondNumber).") 变量声明有几种形式,用于声明不同类型的命名可变值,包括存储变量和计算变量及属性、存储变量和属性观察者,以及静态变量属性。使用的适当形式取决于变量声明的范围和您打算声明的变量类型。 > 注意: -> 您还可以在协议声明的上下文中声明属性,如 中所述。 +> 您还可以在协议声明的上下文中声明属性,参见 。 -您可以通过在子类的属性声明中标记 `override` 声明修饰符来重写属性,如 中所述。 +您可以通过在子类的属性声明中标记 `override` 声明修饰符来重写属性,参见 。 ### 存储变量和存储变量属性 @@ -218,9 +218,9 @@ var <#variable name#>: <#type#> { 您可以在全局范围、函数的局部范围或类、结构体、枚举或扩展声明的上下文中定义这种形式的变量声明。当这种形式的变量声明在全局范围或函数的局部范围内声明时,它被称为*计算变量*。当它在类、结构体或扩展声明的上下文中声明时,它被称为*计算属性*。 -getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter时,可以省略两个子句,直接返回请求的值,如 中所述。但如果提供了 setter 子句,则必须同时提供 getter 子句。 +getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter时,可以省略两个子句,直接返回请求的值,参见 。但如果提供了 setter 子句,则必须同时提供 getter 子句。 -*setter 名称*和括号是可选的。如果您提供了 setter 名称,它将用作 setter 参数的名称。如果您不提供 setter 名称,setter 的默认参数名称是 `newValue`,如 中所述。 +*setter 名称*和括号是可选的。如果您提供了 setter 名称,它将用作 setter 参数的名称。如果您不提供 setter 名称,setter 的默认参数名称是 `newValue`,参见 。 与存储的命名值和存储的变量属性不同,计算得出的命名值或计算得出的属性的值并不存储在内存中。 @@ -243,7 +243,7 @@ var <#variable name#>: <#type#> = <#expression#> { 您可以在全局范围、函数的局部范围或类或结构体声明的上下文中定义这种变量声明形式。当这种形式的变量声明在全局范围或函数的局部范围内声明时,观察者被称为*存储变量观察者*。当它在类或结构声明的上下文中声明时,观察者被称为*属性观察者*。 -您可以为任何存储属性添加属性观察者。您还可以通过在子类中重写属性,为任何继承属性(无论是存储的还是计算的)添加属性观察者,如 中所述。 +您可以为任何存储属性添加属性观察者。您还可以通过在子类中重写属性,为任何继承属性(无论是存储的还是计算的)添加属性观察者,参见 。 构造器*表达式*在类或结构体声明的上下文中是可选的,但在其他地方是必需的。当类型可以从构造器*表达式*中推断时,*类型*标注是可选的。该表达式在您第一次读取属性值时被评估。如果您在读取属性之前覆盖了属性的初始值,则在第一次写入属性之前会评估该表达式。 @@ -373,7 +373,7 @@ newAndOld.x = 200 ``` --> -### 类型变量属性 +### 类型变量属性 要声明一个类型变量属性,请使用 `static` 声明修饰符标记声明。类可以使用 `class` 声明修饰符标记类型计算属性,以允许子类覆盖超类的实现。类型属性的讨论请参见 。 @@ -973,7 +973,7 @@ f(7) // Invalid, missing argument label ``` --> -### 特殊类型的方法 +### 特殊类型的方法 对枚举或结构体的方法,如果修改了 `self`,必须标记为 `mutating` 声明修饰符。 @@ -1019,7 +1019,7 @@ f(7) // Invalid, missing argument label 几种具有特殊名称的方法使函数调用语法变得更加简洁。如果一个类型定义了这些方法之一,该类型的实例可以在函数调用语法中使用。函数调用被理解为对该实例上某个特殊命名方法的调用。 -类、结构体或枚举类型可以通过定义一个 `dynamicallyCall(withArguments:)` 方法或一个 `dynamicallyCall(withKeywordArguments:)` 方法来支持函数调用语法,如 中所述,或者通过定义一个 call-as-function 的方法,如下所述。如果该类型同时定义了一个作为函数调用的方法和 `dynamicCallable` 特性使用的其中一个方法,则在可以使用任一方法的情况下,编译器优先选择 call-as-function 的方法。 +类、结构体或枚举类型可以通过定义一个 `dynamicallyCall(withArguments:)` 方法或一个 `dynamicallyCall(withKeywordArguments:)` 方法来支持函数调用语法,参见 ,或者通过定义一个 call-as-function 的方法,如下所述。如果该类型同时定义了一个作为函数调用的方法和 `dynamicCallable` 特性使用的其中一个方法,则在可以使用任一方法的情况下,编译器优先选择 call-as-function 的方法。 call-as-function 的方法的名称是 `callAsFunction()`,或者另一个以 `callAsFunction(` 开头并添加带标签或不带标签的参数的名称——例如, `callAsFunction(_:_:)` 和 `callAsFunction(something:)` 也是有效的调用作为函数的方法名称。 @@ -1092,7 +1092,7 @@ let someFunction2: (Int, Int) -> Void = callable.callAsFunction(_:scale:) ``` --> -`subscript(dynamicMember:)` 下标为成员查找提供了语法糖,详见 。 +`subscript(dynamicMember:)` 下标为成员查找提供了语法糖,参见 。 ### 抛出函数和方法 @@ -1298,7 +1298,7 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 一个*枚举声明*将一个命名的枚举类型引入到你的程序中。 -枚举声明有两种基本形式,并使用 `enum` 关键字进行声明。使用任一形式声明的枚举的主体包含零个或多个值——称为 *枚举案例*——以及任意数量的声明,包括计算属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor 声明。枚举声明不能包含析构器或协议声明。 +枚举声明有两种基本形式,并使用 `enum` 关键字进行声明。使用任一形式声明的枚举的主体包含零个或多个值——称为*枚举成员*——以及任意数量的声明,包括计算属性、实例方法、类型方法、构造器、类型别名,甚至其他枚举、结构体、类和 actor 声明。枚举声明不能包含析构器或协议声明。 枚举类型可以采用任意数量的协议,但不能从类、结构或其他枚举继承。 @@ -1308,9 +1308,9 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 您可以通过扩展声明扩展枚举类型的行为,如 中所讨论的。 -### 任意类型的枚举案例 +### 任意类型的枚举成员 -以下形式声明了一个枚举类型,其中包含任何类型的枚举案例: +以下形式声明了一个枚举类型,其中包含任何类型的枚举成员: ```swift enum <#enumeration name#>: <#adopted protocols#> { @@ -1321,9 +1321,9 @@ enum <#enumeration name#>: <#adopted protocols#> { 在这种形式中声明的枚举有时在其他编程语言中被称为*区分联合*。 -在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。每个案例的名称必须是唯一的。每个案例还可以指定它存储特定类型的值。这些类型在*关联值类型*元组中指定,紧接在案例名称之后。 +在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举成员,用逗号分隔。每个案例的名称必须是唯一的。每个案例还可以指定它存储特定类型的值。这些类型在*关联值类型*元组中指定,紧接在案例名称之后。 -存储关联值的枚举案例可以用作函数,这些函数创建具有指定关联值的枚举实例。就像函数一样,您可以获取对枚举案例的引用,并在代码中稍后应用它。 +存储关联值的枚举成员可以用作函数,这些函数创建具有指定关联值的枚举实例。就像函数一样,您可以获取对枚举成员的引用,并在代码中稍后应用它。 ```swift enum Number { @@ -1366,7 +1366,7 @@ let evenInts: [Number] = [0, 2, 4, 6].map(f) 枚举可以具有递归结构,也就是说,它们可以有与枚举类型本身实例相关联的值的情况。然而,枚举类型的实例具有值语义,这意味着它们在内存中具有固定的布局。为了支持递归,编译器必须插入一层间接性。 -要为特定的枚举案例启用间接性,请使用 `indirect` 声明修饰符进行标记。间接案例必须具有相关值。 +要为特定的枚举成员启用间接性,请使用 `indirect` 声明修饰符进行标记。间接案例必须具有相关值。 -要为所有具有关联值的枚举案例启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 +要为所有具有关联值的枚举成员启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 一个标记为 `indirect` 修饰符的枚举可以包含具有关联值的情况和没有关联值的情况的混合。然而,它不能包含任何也标记为 `indirect` 修饰符的案例。 @@ -1431,7 +1431,7 @@ enum Tree { ### 带有原始值类型的枚举 -以下表单声明了一个枚举类型,其中包含相同基本类型的枚举案例: +以下表单声明了一个枚举类型,其中包含相同基本类型的枚举成员: ```swift enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { @@ -1440,7 +1440,7 @@ enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { } ``` -在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举案例,用逗号分隔。与第一种形式中的案例不同,每个案例都有一个基础值,称为*原始值*,其基本类型相同。这些值的类型在*原始值类型*中指定,必须表示整数、浮点数、字符串或单个字符。特别是,*原始值类型*必须符合 `Equatable` 协议,并且符合以下协议之一:`ExpressibleByIntegerLiteral` 用于整数字面量,`ExpressibleByFloatLiteral` 用于浮点字面量,`ExpressibleByStringLiteral` 用于包含任意数量字符的字符串字面量,以及 `ExpressibleByUnicodeScalarLiteral` 或 `ExpressibleByExtendedGraphemeClusterLiteral` 用于仅包含单个字符的字符串字面量。每个案例必须具有唯一名称并分配唯一的原始值。 +在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举成员,用逗号分隔。与第一种形式中的案例不同,每个案例都有一个基础值,称为*原始值*,其基本类型相同。这些值的类型在*原始值类型*中指定,必须表示整数、浮点数、字符串或单个字符。特别是,*原始值类型*必须符合 `Equatable` 协议,并且符合以下协议之一:`ExpressibleByIntegerLiteral` 用于整数字面量,`ExpressibleByFloatLiteral` 用于浮点字面量,`ExpressibleByStringLiteral` 用于包含任意数量字符的字符串字面量,以及 `ExpressibleByUnicodeScalarLiteral` 或 `ExpressibleByExtendedGraphemeClusterLiteral` 用于仅包含单个字符的字符串字面量。每个案例必须具有唯一名称并分配唯一的原始值。 -枚举的案例可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举案例满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举案例满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与案例的关联值匹配。例如: +枚举的案例可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举成员满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举成员满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与案例的关联值匹配。例如: ```swift protocol SomeProtocol { @@ -1778,7 +1778,7 @@ protocol SomeProtocol: AnyObject { 协议是命名类型,因此它们可以出现在代码中与其他命名类型相同的位置,如 中所讨论的。然而,您无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 -您可以使用协议来声明类或结构体的代理应该实现哪些方法,如 中所述。 +您可以使用协议来声明类或结构体的代理应该实现哪些方法,参见 。 > 协议声明的语法: > @@ -2024,7 +2024,7 @@ protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } 一个*构造器声明*在您的程序中引入了一个类、结构或枚举的构造器。构造器声明使用 `init` 关键字声明,并有两种基本形式。 -结构体、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,如 中所述。 +结构体、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,参见 。 以下形式声明了结构体、枚举和类的指定构造器的构造器: @@ -2601,9 +2601,9 @@ subscript (<#parameters#>) -> <#return type#> { 您可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与您正在重载的不同。您还可以覆盖从超类继承的下标声明。当您这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 -下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,详见 。 +下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,参见 。 -您还可以在协议声明的上下文中声明下标,详见 。 +您还可以在协议声明的上下文中声明下标,参见 。 有关下标的更多信息以及下标声明的示例,请参见 。 @@ -2794,7 +2794,6 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 - `weak`:将此修饰符应用于存储变量或存储变量属性,以指示该变量或属性对作为其值存储的对象具有弱引用。变量或属性的类型必须是可选类类型。如果在对象被释放后访问该变量或属性,其值为 `nil`。有关 `weak` 修饰符的示例和更多信息,请参见 。 - ### 访问控制级别 Swift 提供五种访问控制级别:open、public、internal、file private 和 private。您可以使用以下访问级别修饰符之一标记声明,以指定声明的访问级别。访问控制的详细信息请参见 。 @@ -2840,7 +2839,7 @@ Swift 提供五种访问控制级别:open、public、internal、file private > > *actor-isolation-modifier* → **`nonisolated`** -> Beta 软件: +> Beta 软件: > > 本文件包含有关正在开发的 API 或技术的初步信息。此信息可能会更改,按照本文件实施的软件应与最终操作系统软件进行测试。 > From ebb555b0374e3e2895c8ce360310dae5c5bf2801 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 4 Sep 2024 10:38:58 +0800 Subject: [PATCH 58/67] fix: term you --- .../ReferenceManual/Declarations.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 3ffcc4ed..b05ff64b 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -28,11 +28,11 @@ ## 顶级代码 -Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他命名声明可以被同一模块中每个源文件的代码访问。您可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 。 +Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他命名声明可以被同一模块中每个源文件的代码访问。你可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 。 有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。 -您编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。 +你编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。 > 顶级声明的语法: > @@ -89,7 +89,7 @@ import <#module#>.<#submodule#> ## 常量声明 -*常量声明*在您的程序中引入一个名为值的常量。常量声明使用 `let` 关键字声明,具有以下形式: +*常量声明*在你的程序中引入一个名为值的常量。常量声明使用 `let` 关键字声明,具有以下形式: ```swift let <#constant name#>: <#type#> = <#expression#> @@ -100,7 +100,7 @@ let <#constant name#>: <#type#> = <#expression#> 当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要在第一次读取其值之前保证已设置值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器证明在读取之前值已被确定设置。 > 注意: -> 确定性初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果您可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 +> 确定性初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果你可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 -您可以使用以下形式之一覆盖参数标签的默认行为: +你可以使用以下形式之一覆盖参数标签的默认行为: ```swift <#argument label#> <#parameter name#>: <#parameter type#> @@ -643,7 +643,7 @@ func someFunction(a: inout A, b: consuming B, c: C) { ... } #### 输入输出参数 -默认情况下,Swift 中的函数参数是按值传递的:在函数内部所做的任何更改在调用者中不可见。要改为使用输入输出参数,您需要应用 `inout` 参数修饰符。 +默认情况下,Swift 中的函数参数是按值传递的:在函数内部所做的任何更改在调用者中不可见。要改为使用输入输出参数,你需要应用 `inout` 参数修饰符。 ```swift func someFunction(a: inout Int) { @@ -681,7 +681,7 @@ func someFunction(a: inout Int) { someFunction(&someValue) ``` -出于同样的原因,您不能将相同的值传递给多个输入输出参数。 +出于同样的原因,你不能将相同的值传递给多个输入输出参数。 ```swift var someValue: Int @@ -704,7 +704,7 @@ someFunction(&someValue, &someValue) behavioral differences that happen because of call by reference. --> -一个捕获输入输出参数的闭包或嵌套函数必须是非逃逸的。如果您需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 +一个捕获输入输出参数的闭包或嵌套函数必须是非逃逸的。如果你需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 ```swift func someFunction(a: inout Int) -> () -> Int { @@ -729,7 +729,7 @@ func someFunction(a: inout Int) -> () -> Int { ``` --> -如果您需要捕获并修改一个 in-out 参数,请使用一个显式的局部副本,例如在多线程代码中,确保所有修改在函数返回之前都已完成。 +如果你需要捕获并修改一个 in-out 参数,请使用一个显式的局部副本,例如在多线程代码中,确保所有修改在函数返回之前都已完成。 ```swift func multithreadedFunction(queue: DispatchQueue, x: inout Int) { @@ -799,9 +799,9 @@ func multithreadedFunction(queue: DispatchQueue, x: inout Int) { #### 借用和消耗参数 -默认情况下,Swift 使用一套规则在函数调用之间自动管理对象生命周期,在需要时复制值。默认规则旨在在大多数情况下最小化开销——如果您想要更具体的控制,可以应用 `borrowing` 或 `consuming` 参数修饰符。在这种情况下,使用 `copy` 显式标记复制操作。 +默认情况下,Swift 使用一套规则在函数调用之间自动管理对象生命周期,在需要时复制值。默认规则旨在在大多数情况下最小化开销——如果你想要更具体的控制,可以应用 `borrowing` 或 `consuming` 参数修饰符。在这种情况下,使用 `copy` 显式标记复制操作。 -无论您是否使用默认规则,Swift 确保在所有情况下对象的生命周期和所有权都得到正确管理。这些参数修饰符仅影响特定使用模式的相对效率,而不影响正确性。 +无论你是否使用默认规则,Swift 确保在所有情况下对象的生命周期和所有权都得到正确管理。这些参数修饰符仅影响特定使用模式的相对效率,而不影响正确性。 -call-as-function 的方法和来自 `dynamicCallable` 特性的方法在将多少信息编码到类型系统与在运行时可能的动态行为之间做出了不同的权衡。当您声明一个 call-as-function 的方法时,您需要指定参数的数量,以及每个参数的类型和标签。`dynamicCallable` 特性的方法仅指定用于保存参数数组的类型。 +call-as-function 的方法和来自 `dynamicCallable` 特性的方法在将多少信息编码到类型系统与在运行时可能的动态行为之间做出了不同的权衡。当你声明一个 call-as-function 的方法时,你需要指定参数的数量,以及每个参数的类型和标签。`dynamicCallable` 特性的方法仅指定用于保存参数数组的类型。 定义一个 call-as-function,或者来自 `dynamicCallable` 特性的方法,并不允许你在函数调用表达式以外的任何上下文中将该类型的实例用作函数。例如: @@ -1114,9 +1114,9 @@ func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> 调用抛出函数或方法的必须被包裹在一个 `try` 或 `try!` 表达式中(即,在 `try` 或 `try!` 操作符的作用域内)。 -一个函数的类型包括它是否可以抛出错误以及它抛出什么类型的错误。这种子类型关系意味着,例如,您可以在期望抛出错误的上下文中使用一个不抛出错误的函数。有关抛出函数类型的更多信息,请参见 。有关处理具有显式类型的错误的示例,请参见 。 +一个函数的类型包括它是否可以抛出错误以及它抛出什么类型的错误。这种子类型关系意味着,例如,你可以在期望抛出错误的上下文中使用一个不抛出错误的函数。有关抛出函数类型的更多信息,请参见 。有关处理具有显式类型的错误的示例,请参见 。 -您不能仅仅根据函数是否可以抛出错误来重载函数。也就是说,您可以根据函数的 *参数* 是否可以抛出错误来重载函数。 +你不能仅仅根据函数是否可以抛出错误来重载函数。也就是说,你可以根据函数的 *参数* 是否可以抛出错误来重载函数。 抛出方法不能覆盖非抛出方法,抛出方法也不能满足非抛出方法的协议要求。也就是说,非抛出方法可以覆盖抛出方法,非抛出方法可以满足抛出方法的协议要求。 @@ -1140,7 +1140,7 @@ func someFunction(callback: () throws -> Void) rethrows { ``` --> -重新抛出的函数或方法只能在 `catch` 子句中包含 `throw` 语句。这使得您可以在 `do`-`catch` 语句中调用抛出函数,并通过抛出不同的错误在 `catch` 子句中处理错误。此外,`catch` 子句必须仅处理由重新抛出函数的抛出参数抛出的错误。例如,以下是无效的,因为 `catch` 子句将处理由 `alwaysThrows()` 抛出的错误。 +重新抛出的函数或方法只能在 `catch` 子句中包含 `throw` 语句。这使得你可以在 `do`-`catch` 语句中调用抛出函数,并通过抛出不同的错误在 `catch` 子句中处理错误。此外,`catch` 子句必须仅处理由重新抛出函数的抛出参数抛出的错误。例如,以下是无效的,因为 `catch` 子句将处理由 `alwaysThrows()` 抛出的错误。 ```swift func alwaysThrows() throws { @@ -1231,9 +1231,9 @@ func <#function name#>(<#parameters#>) async -> <#return type#> { 对异步函数或方法的调用必须包装在一个 `await` 表达式中——也就是说,它们必须在 `await` 操作符的作用域内。 -`async` 关键字是函数类型的一部分,同步函数是异步函数的子类型。因此,您可以覆盖异在期望异步函数的上下文中使用同步函数。例如,您可以用同步方法步方法,并且同步方法可以满足需要异步方法的协议要求。 +`async` 关键字是函数类型的一部分,同步函数是异步函数的子类型。因此,你可以覆盖异在期望异步函数的上下文中使用同步函数。例如,你可以用同步方法步方法,并且同步方法可以满足需要异步方法的协议要求。 -您可以根据函数是否是异步的来重载函数。在调用位置,上下文决定使用哪个重载:在异步上下文中,使用异步函数;在同步上下文中,使用同步函数。 +你可以根据函数是否是异步的来重载函数。在调用位置,上下文决定使用哪个重载:在异步上下文中,使用异步函数;在同步上下文中,使用同步函数。 一异步方法不能覆盖同步方法,异步方法也不能满足同步方法的协议要求。也就是说,同步方法可以覆盖异步方法,且同步方法可以满足异步方法的协议要求。 @@ -1259,7 +1259,7 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 不返回的函数或方法可以被调用,以结束守卫语句的 `else` 子句,如在 中讨论的。 -您可以重写一个不返回的方法,但新方法必须保持其返回类型和不返回值的行为。 +你可以重写一个不返回的方法,但新方法必须保持其返回类型和不返回值的行为。 > 函数声明的语法: > @@ -1306,7 +1306,7 @@ Swift 定义了一个 [`Never`][] 类型,表示一个函数或方法不会返 像结构体但不同于类,枚举是值类型;当枚举的实例被赋值给变量或常量,或作为参数传递给函数调用时,会被复制。有关值类型的信息,请参见 。 -您可以通过扩展声明扩展枚举类型的行为,如 中所讨论的。 +你可以通过扩展声明扩展枚举类型的行为,如 中所讨论的。 ### 任意类型的枚举成员 @@ -1323,7 +1323,7 @@ enum <#enumeration name#>: <#adopted protocols#> { 在这种形式中,每个案例块由 `case` 关键字组成,后面跟着一个或多个枚举成员,用逗号分隔。每个案例的名称必须是唯一的。每个案例还可以指定它存储特定类型的值。这些类型在*关联值类型*元组中指定,紧接在案例名称之后。 -存储关联值的枚举成员可以用作函数,这些函数创建具有指定关联值的枚举实例。就像函数一样,您可以获取对枚举成员的引用,并在代码中稍后应用它。 +存储关联值的枚举成员可以用作函数,这些函数创建具有指定关联值的枚举实例。就像函数一样,你可以获取对枚举成员的引用,并在代码中稍后应用它。 ```swift enum Number { @@ -1447,7 +1447,7 @@ enum <#enumeration name#>: <#raw-value type#>, <#adopted protocols#> { This list is shorter because these five protocols are explicitly supported in the compiler. --> -如果原始值类型被指定为 `Int`,并且您没有显式地为这些情况分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的情况将隐式地被分配一个原始值,该值是从前一个案例的原始值自动递增的。 +如果原始值类型被指定为 `Int`,并且你没有显式地为这些情况分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的情况将隐式地被分配一个原始值,该值是从前一个案例的原始值自动递增的。 ```swift enum ExampleEnum: Int { @@ -1467,7 +1467,7 @@ enum ExampleEnum: Int { 在上述示例中,`ExampleEnum.a` 的原始值为 `0`,而 `ExampleEnum.b` 的值为 `1`。由于 `ExampleEnum.c` 的值被显式设置为 `5`,因此 `ExampleEnum.d` 的值自动从 `5` 增加,结果为 `6`。 -如果原始值类型被指定为 `String`,并且您没有显式地为各个情况分配值,则每个未分配的案例会隐式地分配一个与该案例名称相同文本的字符串。 +如果原始值类型被指定为 `String`,并且你没有显式地为各个情况分配值,则每个未分配的案例会隐式地分配一个与该案例名称相同文本的字符串。 ```swift enum GamePlayMode: String { @@ -1487,7 +1487,7 @@ enum GamePlayMode: String { 在上述示例中,`GamePlayMode.cooperative` 的原始值是 `"cooperative"`,`GamePlayMode.individual` 的原始值是 `"individual"`,而 `GamePlayMode.competitive` 的原始值是 `"competitive"`。 -具有原始值类型的枚举隐式符合在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败的构造器,其签名为 `init?(rawValue: RawValue)`。您可以使用 `rawValue` 属性访问枚举成员的原始值,如 `ExampleEnum.b.rawValue`。您还可以使用原始值通过调用枚举的可失败构造器来查找相应的案例(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 +具有原始值类型的枚举隐式符合在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败的构造器,其签名为 `init?(rawValue: RawValue)`。你可以使用 `rawValue` 属性访问枚举成员的原始值,如 `ExampleEnum.b.rawValue`。你还可以使用原始值通过调用枚举的可失败构造器来查找相应的案例(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 ### 访问枚举成员 @@ -1581,7 +1581,7 @@ struct <#structure name#>: <#adopted protocols#> { 结构体是值类型;当结构的实例被赋值给变量或常量,或作为参数传递给函数调用时,会被复制。有关值类型的信息,请参见 。 -您可以通过扩展声明扩展结构类型的行为,参见 。 +你可以通过扩展声明扩展结构类型的行为,参见 。 > 结构体声明的语法: > @@ -1632,7 +1632,7 @@ class <#class name#>: <#superclass#>, <#adopted protocols#> { 类是引用类型;当类的实例被赋值给变量或常量,或作为参数传递给函数调用时,是引用而不是复制。有关引用类型的信息,请参见 。 -您可以通过扩展声明扩展类类型的行为,参见 。 +你可以通过扩展声明扩展类类型的行为,参见 。 > 类声明的语法: > @@ -1646,7 +1646,7 @@ class <#class name#>: <#superclass#>, <#adopted protocols#> { ## Actor 声明 -一个 *actor 声明*将一个命名的 actor 类型引入到您的程序中。actor 声明使用 `actor` 关键字声明,具有以下形式: +一个 *actor 声明*将一个命名的 actor 类型引入到你的程序中。actor 声明使用 `actor` 关键字声明,具有以下形式: ```swift actor <#actor name#>: <#adopted protocols#> { @@ -1675,7 +1675,7 @@ actor 实例的属性可以使用点 (`.`) 语法访问,参见 。 -您可以通过扩展声明扩展 actor 类型的行为,参见 。 +你可以通过扩展声明扩展 actor 类型的行为,参见 -如果您需要根据多个具体类型添加条件遵循,请创建一个每个类型都可以遵循的新协议,并在声明条件遵循时使用该协议作为要求。 +如果你需要根据多个具体类型添加条件遵循,请创建一个每个类型都可以遵循的新协议,并在声明条件遵循时使用该协议作为要求。 ```swift protocol SerializableInArray { } @@ -2429,7 +2429,7 @@ extension Array: Serializable where Element: SerializableInArray { 当一个具体类型有条件地遵循一个协议时,该类型隐式地遵循任何具有相同要求的父协议。 -如果您需要一个类型有条件地遵循两个继承自单一父协议的协议,请明确声明对父协议的遵循。这可以避免以不同的要求隐式地两次遵循父协议。 +如果你需要一个类型有条件地遵循两个继承自单一父协议的协议,请明确声明对父协议的遵循。这可以避免以不同的要求隐式地两次遵循父协议。 以下示例明确声明了 `Array` 对 `Loggable` 的条件遵循,以避免在声明其对 `TitledLoggable` 和新的 `MarkedLoggable` 协议的条件遵循时发生冲突。 @@ -2578,7 +2578,7 @@ extension Array: Loggable where Element: MarkedLoggable { } ## 下标声明 -*下标*声明允许您为特定类型的对象添加下标支持,通常用于提供一种方便的语法来访问集合、列表或序列中的元素。下标声明使用 `subscript` 关键字声明,具有以下形式: +*下标*声明允许你为特定类型的对象添加下标支持,通常用于提供一种方便的语法来访问集合、列表或序列中的元素。下标声明使用 `subscript` 关键字声明,具有以下形式: ```swift subscript (<#parameters#>) -> <#return type#> { @@ -2597,13 +2597,13 @@ subscript (<#parameters#>) -> <#return type#> { 与计算属性一样,下标声明支持读取和写入所访问元素的值。getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter 时,可以省略两个子句,直接返回请求的值。也就是说,如果提供了 setter 子句,则必须同时提供 getter 子句。 -*setter 名称*和括号是可选的。如果您提供了 setter 名称,它将用作 setter 的参数名称。如果您不提供 setter 名称,setter 的默认参数名称是 `value`。setter 的参数类型与*返回类型* 同。 +*setter 名称*和括号是可选的。如果你提供了 setter 名称,它将用作 setter 的参数名称。如果你不提供 setter 名称,setter 的默认参数名称是 `value`。setter 的参数类型与*返回类型* 同。 -您可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与您正在重载的不同。您还可以覆盖从超类继承的下标声明。当您这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 +你可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与你正在重载的不同。你还可以覆盖从超类继承的下标声明。当你这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 -下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,您可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,参见 。 +下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,你可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,参见 。 -您还可以在协议声明的上下文中声明下标,参见 。 +你还可以在协议声明的上下文中声明下标,参见 。 有关下标的更多信息以及下标声明的示例,请参见 。 @@ -2660,9 +2660,9 @@ macro <#name#> = <#macro implementation#> ## 操作符声明 -*运算符声明*将新的中缀、前缀或后缀运算符引入到您的程序中,并使用 `operator` 关键字进行声明。 +*运算符声明*将新的中缀、前缀或后缀运算符引入到你的程序中,并使用 `operator` 关键字进行声明。 -您可以声明三种不同优先级的运算符:中缀、前缀和后缀。运算符的*优先级*指定了运算符相对于其操作数的相对位置。 +你可以声明三种不同优先级的运算符:中缀、前缀和后缀。运算符的*优先级*指定了运算符相对于其操作数的相对位置。 运算符声明有三种基本形式,每种形式对应一种结合性(fixity)。运算符的结合性通过在 `operator` 关键字之前标注 `infix`、`prefix` 或 `postfix` 声明修饰符来指定。在每种形式中,运算符的名称只能包含 中定义的运算符字符。 @@ -2675,7 +2675,7 @@ infix operator <#operator name#>: <#precedence group#> An *infix operator* is a binary operator that's written between its two operands, such as the familiar addition operator (`+`) in the expression `1 + 2`. 一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式 `1 + 2` 中熟悉的加法运算符`+`。 -中缀运算符可以选择性地指定优先级组。如果您省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 +中缀运算符可以选择性地指定优先级组。如果你省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 以下形式声明了一个新的前缀运算符: @@ -2731,7 +2731,7 @@ precedencegroup <#precedence group name#> { Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator_declarations)。 -运算符的*结合性*指定了在没有分组括号的情况下,具有相同优先级的运算符序列是如何分组的。通过写入上下文敏感的关键字之一来指定运算符的结合性:`left`、`right` 或 `none` ——如果您省略结合性,默认值为 `none`。左结合的运算符从左到右分组。例如,减法运算符(`-`)是左结合的,因此表达式`4 - 5 - 6` 被分组为 `(4 - 5) - 6`,并计算为 `-7`。右结合的运算符从右到左分组,而指定为 `none` 的运算符则完全不结合。相同优先级的非结合运算符不能相邻出现。例如,`<` 运算符的结合性为 `none`,这意味着 `1 < 2 < 3` 不是一个有效的表达式。 +运算符的*结合性*指定了在没有分组括号的情况下,具有相同优先级的运算符序列是如何分组的。通过写入上下文敏感的关键字之一来指定运算符的结合性:`left`、`right` 或 `none` ——如果你省略结合性,默认值为 `none`。左结合的运算符从左到右分组。例如,减法运算符(`-`)是左结合的,因此表达式`4 - 5 - 6` 被分组为 `(4 - 5) - 6`,并计算为 `-7`。右结合的运算符从右到左分组,而指定为 `none` 的运算符则完全不结合。相同优先级的非结合运算符不能相邻出现。例如,`<` 运算符的结合性为 `none`,这意味着 `1 < 2 < 3` 不是一个有效的表达式。 *赋值*优先级组的设置指定了运算符在包含可选链操作中的优先级。当设置为 `true` 时,对应优先级组中的运算符在可选链操作期间使用与 Swift 标准库中的赋值运算符相同的分组规则。否则,当设置为 `false` 或省略时,该优先级组中的运算符将遵循与不执行赋值的运算符相同的可选链规则。 @@ -2762,7 +2762,7 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 - `class`:将此修饰符应用于类的成员,以指示该成员是类本身的成员,而不是类实例的成员。具有此修饰符且没有 `final` 修饰符的超类成员可以被子类重写。 -- `dynamic`:将此修饰符应用于可以用 Objective-C 表示的类的任何成员。当您使用 `dynamic` 修饰符标记成员声明时,对该成员的访问始终通过 Objective-C 运行时动态分派。对该成员的访问永远不会被编译器内联或去虚拟化。 +- `dynamic`:将此修饰符应用于可以用 Objective-C 表示的类的任何成员。当你使用 `dynamic` 修饰符标记成员声明时,对该成员的访问始终通过 Objective-C 运行时动态分派。对该成员的访问永远不会被编译器内联或去虚拟化。 因为带有 `dynamic` 修饰符的声明是通过 Objective-C 运行时进行调度的,因此它们必须标记为 `objc` 属性。 @@ -2790,19 +2790,19 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 - `unowned(safe)`:`unowned` 的明确拼写。 -- `unowned(unsafe)`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,您将访问对象曾经所在位置的内存,这是一种不安全的内存操作。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,该类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 +- `unowned(unsafe)`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,你将访问对象曾经所在位置的内存,这是一种不安全的内存操作。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,该类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 - `weak`:将此修饰符应用于存储变量或存储变量属性,以指示该变量或属性对作为其值存储的对象具有弱引用。变量或属性的类型必须是可选类类型。如果在对象被释放后访问该变量或属性,其值为 `nil`。有关 `weak` 修饰符的示例和更多信息,请参见 。 ### 访问控制级别 -Swift 提供五种访问控制级别:open、public、internal、file private 和 private。您可以使用以下访问级别修饰符之一标记声明,以指定声明的访问级别。访问控制的详细信息请参见 。 +Swift 提供五种访问控制级别:open、public、internal、file private 和 private。你可以使用以下访问级别修饰符之一标记声明,以指定声明的访问级别。访问控制的详细信息请参见 。 - `open`:将此修饰符应用于声明,以指示该声明可以被与该声明位于同一模块中的代码访问和子类化。标记为 `open` 访问级别修饰符的声明也可以被导入包含该声明的模块的模块中的代码访问和子类化。 - `public`:将此修饰符应用于声明,以指示该声明可以被与该声明位于同一模块中的代码访问和子类化。标记为 `public` 访问级别修饰符的声明也可以被导入包含该声明的模块的模块中的代码访问(但不能被子类化)。 -- `package`:将此修饰符应用于声明,以指示该声明只能被与声明在同一包中的代码访问。包是您在使用的构建系统中定义的代码分发单元。当构建系统编译代码时,它通过将 `-package-name` 标志传递给 Swift 编译器来指定包名称。如果构建系统在构建它们时指定相同的包名称,则两个模块属于同一个包。 +- `package`:将此修饰符应用于声明,以指示该声明只能被与声明在同一包中的代码访问。包是你在使用的构建系统中定义的代码分发单元。当构建系统编译代码时,它通过将 `-package-name` 标志传递给 Swift 编译器来指定包名称。如果构建系统在构建它们时指定相同的包名称,则两个模块属于同一个包。 - `internal`:将此修饰符应用于声明,以指示该声明只能被与声明在同一模块中的代码访问。默认情况下,大多数声明隐式标记为 `internal` 访问级别修饰符。 @@ -2818,7 +2818,7 @@ Swift 提供五种访问控制级别:open、public、internal、file private - 在类型声明中声明的私有成员可以从该类型的扩展中访问。在一个扩展中声明的私有成员可以从其他扩展和扩展类型的声明中访问。 -每个上述访问级别修饰符可选择性地接受一个参数,该参数由括号中包含的 `set` 关键字组成——例如,`private(set)`。当您想要为变量或下标的setter指定一个小于或等于变量或下标本身的访问级别时,请使用这种形式的访问级别修饰符,如 中所讨论的。 +每个上述访问级别修饰符可选择性地接受一个参数,该参数由括号中包含的 `set` 关键字组成——例如,`private(set)`。当你想要为变量或下标的setter指定一个小于或等于变量或下标本身的访问级别时,请使用这种形式的访问级别修饰符,如 中所讨论的。 > 声明修饰语的语法: > From 02495bfb38e5beaf981f032f4d4b71ce7fe41efb Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 4 Sep 2024 11:08:08 +0800 Subject: [PATCH 59/67] fix: missing translation --- .../ReferenceManual/Declarations.md | 93 +++++++++---------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index b05ff64b..67aac775 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -583,7 +583,7 @@ func <#function name#>(<#parameters#>) { ```swift func f(x: Int, y: Int) -> Int { return x + y } -f(x: 1, y: 2) // both x and y are labeled +f(x: 1, y: 2) // x 和 y 都带有标签 ``` @@ -614,8 +614,8 @@ _ <#parameter name#>: <#parameter type#> 在参数名称前加下划线(`_`)可以抑制参数标签。相应的参数在函数或方法调用中必须没有标签。 ```swift -func repeatGreeting(_ greeting: String, count n: Int) { /* Greet n times */ } -repeatGreeting("Hello, world!", count: 2) // count is labeled, greeting is not +func repeatGreeting(_ greeting: String, count n: Int) { /* 打招呼 n 次 */ } +repeatGreeting("Hello, world!", count: 2) // count 带有标签,greeting 没有 ``` -在这个例子中,`firstNumber` 是值 `10` 的命名常量,而 `secondNumber` 是值 `42` 的命名常量。现在这两个常量可以独立使用: +在这个例子中,`firstNumber` 是值 `10` 的具名常量,而 `secondNumber` 是值 `42` 的具名常量。现在这两个常量可以独立使用: ```swift print("The first number is \(firstNumber).") -// Prints "The first number is 10." +// 打印 "The first number is 10." print("The second number is \(secondNumber).") -// Prints "The second number is 42." +// 打印 "The second number is 42." ``` -`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外设置值时被调用。 +`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。 `willSet` 观察者在变量或属性的值被设置之前被调用。新值作为常量传递给 `willSet` 观察者,因此在 `willSet` 子句的实现中无法更改。`didSet` 观察者在新值被设置后立即被调用。与 `willSet` 观察者不同,变量或属性的旧值会传递给 `didSet` 观察者,以防你仍然需要访问它。也就是说,如果你在其自己的 `didSet` 观察者子句中给变量或属性赋值,那么你赋的这个新值将替代刚刚设置并传递给 `willSet` 观察者的值。 @@ -286,8 +286,8 @@ class Superclass { } } -// This subclass doesn't refer to oldValue in its observer, so the -// superclass's getter is called only once to print the value. +// 这个子类在它的观察器中没有引用 oldValue, +// 因此父类的 getter 只会被调用一次来打印 class New: Superclass { override var x: Int { didSet { print("New value \(x)") } @@ -295,12 +295,13 @@ class New: Superclass { } let new = New() new.x = 100 -// Prints "Setter was called" -// Prints "Getter was called" -// Prints "New value 100" +// 打印 "Setter was called" +// 打印 "Getter was called" +// 打印 "New value 100" -// This subclass refers to oldValue in its observer, so the superclass's -// getter is called once before the setter, and again to print the value. +// 这个子类在它的观察器中引用了 oldValue, +// 因此父类的 getter 在 setter 之前会被调用一次, +// 然后再次调用以打印该值。 class NewAndOld: Superclass { override var x: Int { didSet { print("Old value \(oldValue) - new value \(x)") } @@ -308,10 +309,10 @@ class NewAndOld: Superclass { } let newAndOld = NewAndOld() newAndOld.x = 200 -// Prints "Getter was called" -// Prints "Setter was called" -// Prints "Getter was called" -// Prints "Old value 12 - new value 200" +// 打印 "Getter was called" +// 打印 "Setter was called" +// 打印 "Getter was called" +// 打印 "Old value 12 - new value 200" ``` -你可以使用以下形式之一覆盖参数标签的默认行为: +你可以使用以下形式之一覆盖实数标签的默认行为: ```swift <#argument label#> <#parameter name#>: <#parameter type#> @@ -613,7 +613,7 @@ _ <#parameter name#>: <#parameter type#> 在参数名称之前添加一个名称为参数提供了一个显式的实参标签,该标签可以与参数名称不同。相应的参数在函数或方法调用中必须使用给定的实参标签。 -在参数名称前加下划线(`_`)可以抑制参数标签。相应的参数在函数或方法调用中必须没有标签。 +在参数名称前加下划线(`_`)可以抑制实数标签。相应的参数在函数或方法调用中必须没有标签。 ```swift func repeatGreeting(_ greeting: String, count n: Int) { /* 打招呼 n 次 */ } @@ -643,9 +643,9 @@ repeatGreeting("Hello, world!", count: 2) // count 带有标签,greeting 没 func someFunction(a: inout A, b: consuming B, c: C) { ... } ``` -#### 输入输出参数 +#### In-Out 参数 -默认情况下,Swift 中的函数参数是按值传递的:在函数内部所做的任何更改在调用者中不可见。要改为使用输入输出参数,你需要应用 `inout` 参数修饰符。 +默认情况下,Swift 中的函数参数是按值传递的:在函数内进行的任何更改对调用者都是不可见的。如果需要传入一个 in-out 参数,可以使用 `inout` 参数修饰符。 ```swift func someFunction(a: inout Int) { @@ -653,7 +653,7 @@ func someFunction(a: inout Int) { } ``` -在调用包含输入输出参数的函数时,输入输出参数必须以一个和号 (`&`) 开头,以标记该函数调用可以改变参数的值。 +当调用包含 in-out 参数的函数时,必须在 in-out 参数前加上 &(与符号),以表明函数调用可以更改该参数的值。 ```swift var x = 7 @@ -661,15 +661,15 @@ someFunction(&x) print(x) // 打印 "8" ``` -输入输出参数的传递方式如下: +In-out 参数的传递方式如下: 1. 当函数被调用时,参数的值会被复制。 2. 在函数体内,副本被修改。 3. 当函数返回时,副本的值被赋给原始参数。 -这种行为被称为 *copy-in copy-out* 或 *值传递*。例如,当一个计算属性或一个带观察者的属性作为输入输出参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。 +这种行为被称为 *copy-in copy-out* 或*按值结果调用*。例如,当一个计算属性或一个带观察者的属性作为 in-out 参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。 -作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。优化后的行为被称为 *引用传递*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。 +作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。优化后的行为被称为*按引用调用*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。 在函数内,不要访问作为 in-out 参数传递的值,即使原始值在当前作用域中可用。访问原始值是对该值的同时访问,这违反了内存独占性。 @@ -683,7 +683,7 @@ func someFunction(a: inout Int) { someFunction(&someValue) ``` -出于同样的原因,你不能将相同的值传递给多个输入输出参数。 +出于同样的原因,你不能将相同的值传递给多个 in-out 参数。 ```swift var someValue: Int @@ -706,7 +706,7 @@ someFunction(&someValue, &someValue) behavioral differences that happen because of call by reference. --> -一个捕获输入输出参数的闭包或嵌套函数必须是非逃逸的。如果你需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 +捕获 in-out 参数的闭包或嵌套函数必须是非逃逸的。如果你需要捕获一个 in-out 参数而不对其进行修改,请使用捕获列表显式地以不可变方式捕获该参数。 ```swift func someFunction(a: inout Int) -> () -> Int { @@ -763,7 +763,7 @@ func multithreadedFunction(queue: DispatchQueue, x: inout Int) { ``` --> -有关输入输出参数的更多讨论和示例,请参见 。 +有关 in-out 参数的更多讨论和示例,请参见 .。 -有关更多信息以及查看与相关值类型相关的案例示例,请参见 。 +有关更多信息以及查看枚举关联值的示例,请参见 。 #### 间接枚举 枚举可以具有递归结构,也就是说,它们可以有与枚举类型本身实例相关联的值的情况。然而,枚举类型的实例具有值语义,这意味着它们在内存中具有固定的布局。为了支持递归,编译器必须插入一层间接性。 -要为特定的枚举成员启用间接性,请使用 `indirect` 声明修饰符进行标记。间接案例必须具有相关值。 +要为特定的枚举成员启用间接性,请使用 `indirect` 声明修饰符进行标记。间接枚举成员必须具有关联值。 -要为所有具有关联值的枚举成员启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的情况时,这样做非常方便。 +要为所有具有关联值的枚举成员启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的成员时,这样做非常方便。 -一个标记为 `indirect` 修饰符的枚举可以包含具有关联值的情况和没有关联值的情况的混合。然而,它不能包含任何也标记为 `indirect` 修饰符的案例。 +一个标记为 `indirect` 修饰符的枚举可以包含同时有关联值的成员和没有关联值的成员。然而,它不能包含任何也标记为 `indirect` 修饰符的成员。 -如果原始值类型被指定为 `Int`,并且你没有显式地为这些情况分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的情况将隐式地被分配一个原始值,该值是从前一个案例的原始值自动递增的。 +如果原始值类型被指定为 `Int`,并且你没有显式地为这些成员分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的成员将隐式地被分配一个原始值,该值是从前一个成员的原始值自动递增的。 ```swift enum ExampleEnum: Int { @@ -1467,7 +1467,7 @@ enum ExampleEnum: Int { 在上述示例中,`ExampleEnum.a` 的原始值为 `0`,而 `ExampleEnum.b` 的值为 `1`。由于 `ExampleEnum.c` 的值被显式设置为 `5`,因此 `ExampleEnum.d` 的值自动从 `5` 增加,结果为 `6`。 -如果原始值类型被指定为 `String`,并且你没有显式地为各个情况分配值,则每个未分配的案例会隐式地分配一个与该案例名称相同文本的字符串。 +如果原始值类型被指定为 `String`,并且你没有显式地为各个成员分配值,则每个未分配的成员会隐式地分配一个与该成员名称相同文本的字符串。 ```swift enum GamePlayMode: String { @@ -1487,13 +1487,13 @@ enum GamePlayMode: String { 在上述示例中,`GamePlayMode.cooperative` 的原始值是 `"cooperative"`,`GamePlayMode.individual` 的原始值是 `"individual"`,而 `GamePlayMode.competitive` 的原始值是 `"competitive"`。 -具有原始值类型的枚举隐式符合在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败的构造器,其签名为 `init?(rawValue: RawValue)`。你可以使用 `rawValue` 属性访问枚举成员的原始值,如 `ExampleEnum.b.rawValue`。你还可以使用原始值通过调用枚举的可失败构造器来查找相应的案例(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 +具有原始值类型的枚举隐式遵循在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败构造器,其签名为 `init?(rawValue: RawValue)`。你可以使用 `rawValue` 属性访问枚举成员的原始值,如 `ExampleEnum.b.rawValue`。你还可以使用原始值通过调用枚举的可失败构造器来查找相应的成员(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 ### 访问枚举成员 要引用枚举类型的案例,请使用点(`.`)语法,如 `EnumerationType.enumerationCase` 所示。当枚举类型可以从上下文中推断时,可以省略它(仍然需要点),参见 。 -要检查枚举成员的值,请使用 `switch` 语句,如 中所示。枚举类型与 `switch` 语句的案例块中的枚举成员模式进行模式匹配,参见 。 +要检查枚举成员的值,请使用 `switch` 语句,如 中所示。枚举类型与 `switch` 语句的 case 块中的枚举成员模式进行模式匹配,参见 -枚举的案例可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举成员满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举成员满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与案例的关联值匹配。例如: +枚举的成员可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举成员满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举成员满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与枚举成员的关联值匹配。例如: ```swift protocol SomeProtocol { @@ -1776,7 +1776,7 @@ protocol SomeProtocol: AnyObject { > 注意: > 如果一个协议标记了 `objc` 属性,则 `AnyObject` 要求隐式应用于该协议;无需明确将该协议标记为 `AnyObject` 要求。 -协议是命名类型,因此它们可以出现在代码中与其他命名类型相同的位置,如 中所讨论的。然而,你无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 +协议是具名类型,因此它们可以出现在代码中与其他具名类型相同的位置,如 中所讨论的。然而,你无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 你可以使用协议来声明类或结构体的代理应该实现哪些方法,参见 。 @@ -1798,17 +1798,17 @@ protocol SomeProtocol: AnyObject { ### 协议属性声明 -协议声明符合的类型必须通过在协议声明的主体中包含一个*协议属性声明*来实现一个属性。协议属性声明具有变量声明的特殊形式: +协议声明遵循的类型必须通过在协议声明的主体中包含一个*协议属性声明*来实现一个属性。协议属性声明具有变量声明的特殊形式: ```swift var <#property name#>: <#type#> { get set } ``` -与其他协议成员声明一样,这些属性声明仅声明符合该协议的类型的 getter 和 setter 要求。因此,你不会在声明它的协议中直接实现 getter 或 setter。 +与其他协议成员声明一样,这些属性声明仅声明遵循该协议的类型的 getter 和 setter 要求。因此,你不会在声明它的协议中直接实现 getter 或 setter。 -getter 和 setter 的要求可以通过符合类型以多种方式满足。如果属性声明同时包含 `get` 和 `set` 关键字,则符合类型可以通过存储变量属性或可读可写的计算属性来实现(即实现了 getter 和 setter 的属性)。然而,该属性声明不能实现为常量属性或只读计算属性。如果属性声明仅包含 `get` 关键字,则可以实现为任何类型的属性。有关实现协议属性要求的符合类型的示例,请参见 。 +getter 和 setter 的要求可以通过遵循类型以多种方式满足。如果属性声明同时包含 `get` 和 `set` 关键字,则遵循类型可以通过存储变量属性或可读可写的计算属性来实现(即实现了 getter 和 setter 的属性)。然而,该属性声明不能实现为常量属性或只读计算属性。如果属性声明仅包含 `get` 关键字,则可以实现为任何类型的属性。有关实现协议属性要求的遵循类型的示例,请参见 。 -在协议声明中声明类型属性要求时,使用 `static` 关键字标记属性声明。符合该协议的结构体和枚举使用 `static` 关键字声明属性,而符合该协议的类则可以使用 `static` 或 `class` 关键字声明属性。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型属性要求提供默认实现的扩展使用 `static` 关键字。 +在协议声明中声明类型属性要求时,使用 `static` 关键字标记属性声明。遵循该协议的结构体和枚举使用 `static` 关键字声明属性,而遵循该协议的类则可以使用 `static` 或 `class` 关键字声明属性。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型属性要求提供默认实现的扩展使用 `static` 关键字。 -调用 `init?` 可失败的初始化器与调用不可失败的初始化器的方式相同,只是你必须处理结果的可选性。 +调用 `init?` 可失败的构造器与调用不可失败的构造器的方式相同,只是你必须处理结果的可选性。 ```swift if let actualInstance = SomeStruct(input: "Hello") { - // do something with the instance of 'SomeStruct' + // 使用 'SomeStruct' 的实例执行操作 } else { - // initialization of 'SomeStruct' failed and the initializer returned 'nil' + // 'SomeStruct' 的初始化失败,初始化器返回了 'nil' } ``` @@ -2176,7 +2176,7 @@ extension <#type name#> where <#requirements#> { 扩展声明的主体包含零个或多个*声明*。这些*声明*可以包括计算属性、计算类型属性、实例方法、类型方法、构造器、下标声明,甚至类、结构体和枚举声明。扩展声明不能包含析构器或协议声明、存储属性、属性观察者或其他扩展声明。协议扩展中的声明不能标记为 `final`。有关包含各种类型声明的扩展的讨论和多个示例,请参见 。 -如果*类型名称*是类、结构体或枚举类型,则扩展该类型。如果*类型名称*是协议类型,则扩展所有符合该协议的类型。 +如果*类型名称*是类、结构体或枚举类型,则扩展该类型。如果*类型名称*是协议类型,则扩展所有遵循该协议的类型。 扩展声明可以扩展具有关联类型的泛型类型或协议,并可以包含*要求*。如果扩展类型的实例或遵循扩展协议的类型的实例满足*要求*,则该实例获得声明中指定的行为。 @@ -2184,7 +2184,7 @@ extension <#type name#> where <#requirements#> { 现有类型的属性、方法和构造器不能在该类型的扩展中被重写。 -扩展声明可以通过指定*采用的协议*,为现有的类、结构体或枚举类型添加协议符合性: +扩展声明可以通过指定*采用的协议*,为现有的类、结构体或枚举类型添加协议遵循: ```swift extension <#type name#>: <#adopted protocols#> where <#requirements#> { @@ -2600,7 +2600,7 @@ subscript (<#parameters#>) -> <#return type#> { 你可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与你正在重载的不同。你还可以覆盖从超类继承的下标声明。当你这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 -下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,你可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有输入输出参数。下标参数可以具有默认值,参见 。 +下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,你可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有 in-out 参数。下标参数可以具有默认值,参见 。 你还可以在协议声明的上下文中声明下标,参见 。 @@ -2635,7 +2635,7 @@ subscript (<#parameters#>) -> <#return type#> { ## 宏声明 -一个*宏声明*引入一个新的宏。它以 `macro` 关键字开始,具有以下形式: +*宏声明*引入一个新的宏。它以 `macro` 关键字开始,具有以下形式: ```swift macro <#name#> = <#macro implementation#> @@ -2663,7 +2663,7 @@ macro <#name#> = <#macro implementation#> 你可以声明三种不同优先级的运算符:中缀、前缀和后缀。运算符的*优先级*指定了运算符相对于其操作数的相对位置。 -运算符声明有三种基本形式,每种形式对应一种结合性(fixity)。运算符的结合性通过在 `operator` 关键字之前标注 `infix`、`prefix` 或 `postfix` 声明修饰符来指定。在每种形式中,运算符的名称只能包含 中定义的运算符字符。 +运算符声明有三种基本形式,每种形式对应一种结合性。运算符的结合性通过在 `operator` 关键字之前标注 `infix`、`prefix` 或 `postfix` 声明修饰符来指定。在每种形式中,运算符的名称只能包含 中定义的运算符字符。 以下形式声明了一个新的中缀运算符: @@ -2671,7 +2671,6 @@ macro <#name#> = <#macro implementation#> infix operator <#operator name#>: <#precedence group#> ``` -An *infix operator* is a binary operator that's written between its two operands, such as the familiar addition operator (`+`) in the expression `1 + 2`. 一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式 `1 + 2` 中熟悉的加法运算符`+`。 中缀运算符可以选择性地指定优先级组。如果你省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 @@ -2757,7 +2756,7 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 ## 声明修饰符 -*声明修饰符* 是修饰声明行为或含义的关键字或上下文敏感关键字。你可以通过在声明的属性(如果有的话)和引入声明的关键字之间,写上适当的关键字或上下文敏感关键字来指定声明修饰符。 +*声明修饰符*是一些关键字或上下文相关的关键字,用于修改声明的行为或含义。你可以通过在声明的属性(如果有的话)和引入声明的关键字之间编写适当的关键字或上下文相关的关键字来指定声明修饰符。 - `class`:将此修饰符应用于类的成员,以指示该成员是类本身的成员,而不是类实例的成员。具有此修饰符且没有 `final` 修饰符的超类成员可以被子类重写。 From fe59179879abc3f508fafd5352f1928bf056b343 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 9 Oct 2024 12:19:58 +0800 Subject: [PATCH 62/67] fix: per code review --- .../ReferenceManual/Declarations.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index e4eaf03b..d48dbe9c 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -2,9 +2,9 @@ 引入类型、运算符、变量以及其他名称和构造。 -一个*声明*将一个新名称或构造引入到你的程序中。例如,你使用声明来引入函数和方法,引入变量和常量,以及定义枚举、结构体、类和协议类型。你还可以使用声明来扩展现有具名类型的行为,并将其他地方声明的符号引入到你的程序中。 +*声明*将在程序中引入一个新的名称或构造例如,你使用声明来引入函数和方法,引入变量和常量,以及定义枚举、结构体、类和协议类型。你还可以使用声明来扩展现有具名类型的行为,并将其他地方声明的符号引入到你的程序中。 -在 Swift 中,大多数声明也是定义,因为它们在声明的同时被实现或初始化。也就是说,由于协议不实现其成员,大多数协议成员仅仅是声明。为了方便起见,并且因为在 Swift 中这种区别并不是那么重要,术语*声明*涵盖了声明和定义。 +在 Swift 中,大多数声明也是定义,因为它们在声明的同时被实现或初始化。但由于协议不实现它的成员,所以协议成员在此仅仅是声明。为了方便起见,而且这种区别在 Swift 中没那么重要,所以术语*声明*涵盖了声明和定义两种含义。 > 声明的语法: > @@ -28,11 +28,11 @@ ## 顶级代码 -Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他具名声明可以被同一模块中每个源文件的代码访问。你可以通过使用访问级别修饰符来覆盖此默认行为,具体说明见 。 +Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他具名声明可以被同一模块中每个源文件的代码访问。你可以使用访问级别修饰符来覆盖此默认行为,具体说明见 。 有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。 -你编译的 Swift 代码可以包含最多以下一种方法来标记顶级入口点,无论代码如何组织成文件和模块:`main` 特性,`NSApplicationMain` 特性,`UIApplicationMain` 特性,`main.swift` 文件,或包含顶级可执行代码的文件。 +编译 Swift 代码生成可执行文件时,无论文件和模块中的代码如何组织,都只能通过以下方法之一来指定顶级入口点:`main` 特性、`NSApplicationMain` 特性、`UIApplicationMain` 特性、`main.swift` 文件,或包含顶级可执行代码的文件。 > 顶级声明的语法: > @@ -69,7 +69,7 @@ Swift 源文件中的顶级代码由零个或多个语句、声明和表达式 import <#module#> ``` -提供更多细节可以限制导入哪些符号——你可以指定特定的子模块或模块或子模块内的特定声明。当使用这种详细形式时,只有被导入的符号(而非声明它的模块)在当前作用域中可用。 +提供更多细节可以限制导入哪些符号——可以指定特定的子模块,也可以指定模块或子模块中特定的声明。使用这种限制后,在当前作用域中,只有被导入的符号是可用的,而不是整个模块中的所有声明。 ```swift import <#import kind#> <#module#>.<#symbol name#> @@ -97,10 +97,10 @@ let <#constant name#>: <#type#> = <#expression#> 常量声明定义了*常量名称*与构造器*表达式*的值之间的不可变绑定;一旦常量的被赋值,就无法更改。也就是说,如果常量是用类对象初始化的,对象本身可以改变,但常量名称与它所指向的对象之间的绑定不能改变。 -当在全局范围内声明常量时,必须用一个值进行初始化。当在函数或方法的上下文中发生常量声明时,可以稍后初始化,只要保证在第一次读取其值之前已为其赋值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须设置值。此分析称为*确定初始化*——编译器保证一个值在读取之前值已被赋值。 +当常量声明在全局作用域时,常量必须赋值。当常量声明在函数或者方法的上下文中时,可以稍后初始化,只要保证在第一次读取其值之前已为其赋值。如果编译器能够证明常量的值从未被读取,则不要求该常量必须赋值。此分析称为*确定初始化*——编译器保证一个值在读取之前值已被赋值。 > 注意: -> 确定初始化无法构建需要领域知识的证明,并且它在条件语句中跟踪状态的能力是有限的。如果你可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 +> 确定初始化无法分析包含特定领域的内容,并且对条件语句中的状态跟踪能力也有限。如果你可以确定常量始终有一个值,但编译器无法证明这一点,请尝试简化设置该值的代码路径,或改用变量声明。 -在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,祥见 。 +在常量声明中,当可以推断出*常量名称*的类型时,类型注释(`:` *type*)是可选的,详见 。 -要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;你不能使用 `class` 或 `final` 声明修饰符来允许或禁止子类重写。类型属性的讨论请参见 。 +要声明一个常量类型属性,请使用 `static` 声明修饰符标记该声明。类的常量类型属性总是隐式为 final;你无法用 class 或 final 声明修饰符实现允许或禁止被子类重写的目的。类型属性的讨论请参见 -`willSet` 和 `didSet` 观察者提供了一种观察(并适当地响应)变量或属性值被设置时的方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。 +`willSet` 和 `didSet` 观察者提供了一种在变量或属性被赋值时的观察(和响应)方式。当变量或属性首次初始化时,观察者不会被调用。相反,它们仅在初始化上下文之外的情况下,值被设置时被调用。 -`willSet` 观察者在变量或属性的值被设置之前被调用。新值作为常量传递给 `willSet` 观察者,因此在 `willSet` 子句的实现中无法更改。`didSet` 观察者在新值被设置后立即被调用。与 `willSet` 观察者不同,变量或属性的旧值会传递给 `didSet` 观察者,以防你仍然需要访问它。也就是说,如果你在其自己的 `didSet` 观察者子句中给变量或属性赋值,那么你赋的这个新值将替代刚刚设置并传递给 `willSet` 观察者的值。 +`willSet` 观察者在变量或属性的值被设置之前被调用。新值作为常量传递给 `willSet` 观察者,因此新值在 `willSet` 子句的实现中无法更改。`didSet` 观察者在新值被设置后立即被调用。与 `willSet` 观察者不同,变量或属性的旧值会传递给 `didSet` 观察者,以防你仍然需要访问它。也就是说,如果你在其自己的 `didSet` 观察者子句中给变量或属性赋值,那么你赋的这个新值将替代刚刚设置并传递给 `willSet` 观察者的值。 *setter 名称*和 `willSet` 与 `didSet` 子句中的括号是可选的。如果提供了 setter 名称,它们将作为 `willSet` 和 `didSet` 观察者的参数名称。如果不提供 setter 名称,`willSet` 观察者的默认参数名称是 `newValue`,而 `didSet` 观察者的默认参数名称是 `oldValue`。 `didSet` 子句在提供 `willSet` 子句时是可选的。同样,在提供 `didSet` 子句时,`willSet` 子句也是可选的。 -如果 `didSet` 观察者的主体引用了旧值,则在调用观察者之前会调用 getter,以使旧值可用。否则,新的值会被存储,而不调用超类的 getter。下面的示例显示了一个由超类定义并被其子类重写以添加观察者的计算属性。 +如果在 `didSet` 主体中引用了旧值,为了使旧值可用,在调用 `didSet` 之前,会先调用 getter。否则,新的值会被存储,而不调用超类的 getter。下面的示例显示了一个由超类定义并被其子类重写以添加观察者的计算属性。 ```swift class Superclass { @@ -287,7 +287,7 @@ class Superclass { } // 这个子类在它的观察器中没有引用 oldValue, -// 因此父类的 getter 只会被调用一次来打印 +// 因此,父类的 getter 方法中的打印语句只会执行一次 class New: Superclass { override var x: Int { didSet { print("New value \(x)") } @@ -551,7 +551,7 @@ func <#function name#>(<#parameters#>) { } ``` -每个参数的类型必须明确指定,而不能被推断出来。如果在参数类型前写上 `inout`,则该参数可以在函数的作用域内被修改。关于 in-out 参数的详细讨论请参见下面的 。 +因为参数类型无法被推断出来,所以函数的每个参数必须明确指定类型。如果在参数类型前写上 `inout`,则该参数可以在函数的作用域内被修改。关于 in-out 参数的详细讨论请参见下面的 。 如果一个函数声明中的*语句*只包含一个表达式,则默认返回该表达式的值。只有在表达式的类型和函数的返回类型不是 `Void`,并且不是像 `Never` 那样没有任何枚举值的枚举时,才会考虑这种隐式返回语法。 @@ -567,7 +567,7 @@ func <#function name#>(<#parameters#>) { TODO: ^-- Add some more here. --> -一个函数定义可以出现在另一个函数声明内部。这种函数被称为*嵌套函数*。 +在函数内部,可以定义另一个函数。这种定义在函数内部的函数,被称为*嵌套函数*。 如果一个嵌套函数捕获了一个保证不会逃逸的值——例如一个 in-out 参数——或者作为一个非逃逸函数参数传递,那么这个嵌套函数就是非逃逸的。否则,嵌套函数就是逃逸的。 @@ -575,13 +575,13 @@ func <#function name#>(<#parameters#>) { ### 参数名称 -函数参数是一个以逗号分隔的列表,其中每个参数都有几种形式之一。在函数调用中,参数的顺序必须与函数声明中的参数顺序匹配。参数列表中最简单的项具有以下形式: +函数的参数是一个以逗号分隔的列表,每个参数都可以是不同的类型。函数调用时的参数顺序必须和函数声明时的参数顺序一致。最简单的参数列表有着如下的形式: ```swift <#parameter name#>: <#parameter type#> ``` -一个参数有一个名称,在函数体内使用,以及一个实参标签,在调用函数或方法时使用。默认情况下,参数名称也用作实参标签。例如: +参数有名称和标签,名称用于在函数内访问参数,标签用于在调用函数时指定参数。默认情况下,参数的名称也可以作为标签。例如: ```swift func f(x: Int, y: Int) -> Int { return x + y } @@ -604,16 +604,16 @@ f(x: 1, y: 2) // x 和 y 都带有标签 Tracking bug is --> -你可以使用以下形式之一覆盖实数标签的默认行为: +你可以使用以下形式(选其一),覆盖参数标签的默认行为: ```swift <#argument label#> <#parameter name#>: <#parameter type#> _ <#parameter name#>: <#parameter type#> ``` -在参数名称之前添加一个名称为参数提供了一个显式的实参标签,该标签可以与参数名称不同。相应的参数在函数或方法调用中必须使用给定的实参标签。 +在参数名称前的名称会作为这个参数的显式实参标签,它可以和参数名称不同。在函数或方法调用时,相对应的参数必须使用这个实参标签。 -在参数名称前加下划线(`_`)可以抑制实数标签。相应的参数在函数或方法调用中必须没有标签。 +参数名称前的下划线(`_`)可以去除参数的实参标签。在函数或方法调用时,相对应的参数必须去除标签。 ```swift func repeatGreeting(_ greeting: String, count n: Int) { /* 打招呼 n 次 */ } @@ -667,9 +667,9 @@ In-out 参数的传递方式如下: 2. 在函数体内,副本被修改。 3. 当函数返回时,副本的值被赋给原始参数。 -这种行为被称为 *copy-in copy-out* 或*按值结果调用*。例如,当一个计算属性或一个带观察者的属性作为 in-out 参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。 +这种行为被称为*拷入拷出(copy-in copy-out)* 或*值结果调用(call by value result)*。例如,当一个计算属性或一个带观察者的属性作为 in-out 参数传递时,它的 getter 在函数调用中被调用,而它的 setter 在函数返回时被调用。 -作为一种优化,当参数是存储在内存物理地址中的值时,函数体内外使用相同的内存位置。优化后的行为被称为*按引用调用*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。 +作为一种优化手段,当参数值存储在内存中的物理地址时,在函数体内部和外部均会使用同一内存位置。这种优化行为被称为*引用调用(call by reference)*; 它满足了 copy-in copy-out 模型的所有要求,同时消除了复制的开销。请使用 copy-in copy-out 给出的模型编写代码,而不依赖于引用传递优化,以便在有或没有优化的情况下都能正确运行。 在函数内,不要访问作为 in-out 参数传递的值,即使原始值在当前作用域中可用。访问原始值是对该值的同时访问,这违反了内存独占性。 @@ -812,7 +812,7 @@ and everything else is borrowing. Where are copies implicitly inserted? --> -`borrowing` 修饰符表示该函数不保留参数的值。在这种情况下,调用者保持对象的所有权,并对对象的生命周期负责。使用 `borrowing` 可以在函数仅暂时使用对象时最小化开销。 +`borrowing` 修饰符表示函数不会保留参数的值。在这种情况下,调用者保持对对象的所有权,并负责对象的生命周期管理。使用 `borrowing` 可以在函数只临时使用对象时,最大限度地减少开销。 ```swift // `isLessThan` 不会保留任一参数 @@ -821,7 +821,7 @@ func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { } ``` -如果函数需要保持参数的值,例如,通过将其存储在全局变量中——你可以使用 `copy` 明确地复制该值。 +如果函数需要保留参数的值,例如,通过将其存储在全局变量中——你可以使用 `copy` 显式地复制该值。 ```swift // 如上所述,但这个 `isLessThan` 还需要记录最小值 @@ -909,7 +909,7 @@ func consumingFunction3(a: consuming A) { ### 特殊类型的参数 -参数可以被忽略,接受可变数量的值,并使用以下形式提供默认值: +参数可以通过以下形式被忽略、接受可变数量的值,以及提供默认值: ```swift _ : <#parameter type#> @@ -917,17 +917,17 @@ _ : <#parameter type#> <#parameter name#>: <#parameter type#> = <#default argument value#> ``` -下划线 (`_`) 参数被明确忽略,无法在函数体内访问。 +下划线 (`_`) 参数被显式忽略,无法在函数体内访问。 带有基本类型名称后面紧跟三个点(`...`)的参数被理解为可变参数。紧跟在可变参数后面的参数必须有一个实参标签。一个函数可以有多个可变参数。可变参数被视为包含基本类型名称元素的数组。例如,可变参数 `Int...` 被视为 `[Int]`。有关使用可变参数的示例,请参见 。 -一个带有等号 (`=`) 的参数及其类型后面的表达式被理解为具有给定表达式的默认值。给定的表达式在调用函数时被评估。如果在调用函数时省略了该参数,则使用默认值。 +带有等号(`=`)且在类型后跟随一个表达式的参数,表示该参数有一个默认值。这个给定的表达式会在函数调用时进行求值。如果在调用函数时省略了该参数,则会使用默认值。 ```swift func f(x: Int = 42) -> Int { return x } f() // 有效,使用默认值 f(x: 7) // 有效,使用提供的值 -f(7) // 无效,缺少参数标签 +f(7) // 无效,缺少实参标签 ``` -call-as-function 的方法和来自 `dynamicCallable` 特性的方法在将多少信息编码到类型系统与在运行时可能的动态行为之间做出了不同的权衡。当你声明一个 call-as-function 的方法时,你需要指定参数的数量,以及每个参数的类型和标签。`dynamicCallable` 特性的方法仅指定用于保存参数数组的类型。 +作为函数调用的方法和来自 `dynamicCallable` 特性的方法在将多少信息编码到类型系统与在运行时可能的动态行为之间做出了不同的权衡。当你声明一个作为函数调用的方法时,你需要指定参数的数量,以及每个参数的类型和标签。`dynamicCallable` 特性的方法仅指定用于保存参数数组的类型。 -定义一个 call-as-function,或者来自 `dynamicCallable` 特性的方法,并不允许你在函数调用表达式以外的任何上下文中将该类型的实例用作函数。例如: +定义一个作为函数调用的方法,或者来自 `dynamicCallable` 特性的方法,并不允许你在函数调用表达式以外的任何上下文中将该类型的实例用作函数。例如: ```swift let someFunction1: (Int, Int) -> Void = callable(_:scale:) // 错误 @@ -1096,7 +1096,7 @@ let someFunction2: (Int, Int) -> Void = callable.callAsFunction(_:scale:) ### 抛出函数和方法 -可以抛出错误的函数和方法必须标记为 `throws` 关键字。这些函数和方法被称为*抛出函数*和*抛出方法*。它们具有以下形式: +可以抛出错误的函数和方法必须标记 `throws` 关键字。这些函数和方法被称为*抛出函数*和*抛出方法*。它们具有以下形式: ```swift func <#function name#>(<#parameters#>) throws -> <#return type#> { @@ -1114,15 +1114,15 @@ func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> 调用抛出函数或方法的必须被包裹在一个 `try` 或 `try!` 表达式中(即,在 `try` 或 `try!` 操作符的作用域内)。 -一个函数的类型包括它是否可以抛出错误以及它抛出什么类型的错误。这种子类型关系意味着,例如,你可以在期望抛出错误的上下文中使用一个不抛出错误的函数。有关抛出函数类型的更多信息,请参见 。有关处理具有显式类型的错误的示例,请参见 。 +函数的类型包括它是否会抛出错误以及它抛出的错误类型。这个子类型关系意味着,例如,你可以在需要抛出错误的上下文中使用不抛出错误的函数。有关抛出错误函数类型的更多信息,请参阅 。有关处理具有明确类型的错误的示例,请参阅 。 -你不能仅仅根据函数是否可以抛出错误来重载函数。也就是说,你可以根据函数的*参数*是否可以抛出错误来重载函数。 +你不能仅根据函数是否会抛出错误来重载一个函数。不过,你可以根据函数的*参数*是否会抛出错误来重载函数。 -抛出方法不能覆盖非抛出方法,抛出方法也不能满足非抛出方法的协议要求。也就是说,非抛出方法可以覆盖抛出方法,非抛出方法可以满足抛出方法的协议要求。 +抛出方法不能重写非抛出方法,且抛出方法也不能满足协议中对非抛出方法的要求。不过,非抛出方法可以重写抛出方法,且非抛出方法也可以满足协议中对会抛出方法的要求。 -### 重新抛出函数和方法 +### 再抛出函数和方法 -函数或方法可以使用 `rethrows` 关键字声明,以指示它仅在其一个函数参数抛出错误时才抛出错误。这些函数和方法被称为*重新抛出函数*和*重新抛出方法*。重新抛出函数和方法必须至少有一个抛出错误的函数参数。 +函数或方法可以使用 `rethrows` 关键字声明,表示它只在其某个函数参数抛出错误时才会抛出错误。这样的函数和方法被称为*再抛出函数(rethrowing functions)*和*再抛出方法(rethrowing methods)*。再抛出函数和方法必须至少有一个会抛出错误的函数参数。 ```swift func someFunction(callback: () throws -> Void) rethrows { @@ -1140,7 +1140,7 @@ func someFunction(callback: () throws -> Void) rethrows { ``` --> -重新抛出的函数或方法只能在 `catch` 子句中包含 `throw` 语句。这使得你可以在 `do`-`catch` 语句中调用抛出函数,并通过抛出不同的错误在 `catch` 子句中处理错误。此外,`catch` 子句必须仅处理由重新抛出函数的抛出参数抛出的错误。例如,以下是无效的,因为 `catch` 子句将处理由 `alwaysThrows()` 抛出的错误。 +再抛出的函数或方法只能在 `catch` 子句中包含 `throw` 语句。这使得你可以在 `do`-`catch` 语句中调用抛出函数,并通过抛出不同的错误在 `catch` 子句中处理错误。此外,`catch` 子句必须仅处理由再抛出函数的抛出参数抛出的错误。例如,以下是无效的,因为 `catch` 子句将处理由 `alwaysThrows()` 抛出的错误。 ```swift func alwaysThrows() throws { @@ -1200,9 +1200,9 @@ func someFunction(callback: () throws -> Void) rethrows { ``` --> -抛出方法不能覆盖重新抛出方法,抛出方法也不能满足重新抛出方法的协议要求。也就是说,重新抛出方法可以覆盖抛出方法,重新抛出方法可以满足抛出方法的协议要求。 +抛出方法不能覆盖再抛出方法,抛出方法也不能满足再抛出方法的协议要求。也就是说,再抛出方法可以覆盖抛出方法,再抛出方法可以满足抛出方法的协议要求。 -在泛型代码中,抛出特定错误类型是重新抛出的替代方案。例如: +在泛型代码中,抛出特定错误类型是再抛出的替代方案。例如: ```swift func someFunction(callback: () throws(E) -> Void) throws(E) { @@ -1210,7 +1210,7 @@ func someFunction(callback: () throws(E) -> Void) throws(E) { } ``` -这种传播错误的方法保留了关于错误的类型信息。然而,与标记一个函数 `rethrows` 不同,这种方法并不阻止该函数抛出相同类型的错误。 +这种传播错误的方法保留了错误的类型信息。然而,与标记一个函数 `rethrows` 不同,这种方法并不阻止该函数抛出相同类型的错误。 -要为所有具有关联值的枚举成员启用间接引用,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的成员时,这样做非常方便。 +要让一个枚举类型的所有用例都支持递归,请使用 `indirect` 修饰符标记整个枚举——当枚举包含许多需要标记为 `indirect` 修饰符的用例时,这样做非常方便。 -一个标记为 `indirect` 修饰符的枚举可以包含同时有关联值的成员和没有关联值的成员。然而,它不能包含任何也标记为 `indirect` 修饰符的成员。 +使用 `indirect` 修饰符标记的枚举类型可以既包含有关联值的用例,同时还可包含没有关联值的用例。但是,它不能再单独使用 `indirect` 修饰符来标记某个用例。 -如果原始值类型被指定为 `Int`,并且你没有显式地为这些成员分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的成员将隐式地被分配一个原始值,该值是从前一个成员的原始值自动递增的。 +如果原始值类型被指定为 `Int`,并且你没有显式地为这些用例分配值,它们将隐式地被分配值 `0`、`1`、`2`,依此类推。每个未分配的 `Int` 类型的用例将隐式地被分配一个原始值,该值是从前一个用例的原始值自动递增的。 ```swift enum ExampleEnum: Int { @@ -1467,7 +1467,7 @@ enum ExampleEnum: Int { 在上述示例中,`ExampleEnum.a` 的原始值为 `0`,而 `ExampleEnum.b` 的值为 `1`。由于 `ExampleEnum.c` 的值被显式设置为 `5`,因此 `ExampleEnum.d` 的值自动从 `5` 增加,结果为 `6`。 -如果原始值类型被指定为 `String`,并且你没有显式地为各个成员分配值,则每个未分配的成员会隐式地分配一个与该成员名称相同文本的字符串。 +如果原始值类型被指定为 `String`,并且你没有显式地为各个用例分配值,则每个未分配的用例会隐式地分配一个与该成员名称相同文本的字符串。 ```swift enum GamePlayMode: String { @@ -1487,13 +1487,13 @@ enum GamePlayMode: String { 在上述示例中,`GamePlayMode.cooperative` 的原始值是 `"cooperative"`,`GamePlayMode.individual` 的原始值是 `"individual"`,而 `GamePlayMode.competitive` 的原始值是 `"competitive"`。 -具有原始值类型的枚举隐式遵循在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败构造器,其签名为 `init?(rawValue: RawValue)`。你可以使用 `rawValue` 属性访问枚举成员的原始值,如 `ExampleEnum.b.rawValue`。你还可以使用原始值通过调用枚举的可失败构造器来查找相应的成员(如果存在),如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的案例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 +具有原始值类型的枚举隐式遵循在 Swift 标准库中定义的 `RawRepresentable` 协议。因此,它们具有 `rawValue` 属性和一个可失败构造器,其签名为 `init?(rawValue: RawValue)`。你可以使用 `rawValue` 属性访问枚举用例的原始值,如 `ExampleEnum.b.rawValue`。你还可以使用原始值通过调用枚举的可失败构造器来查找相应的用例,如 `ExampleEnum(rawValue: 5)`,这将返回一个可选的用例。有关更多信息以及查看具有原始值类型的案例示例,请参见 。 ### 访问枚举成员 -要引用枚举类型的案例,请使用点(`.`)语法,如 `EnumerationType.enumerationCase` 所示。当枚举类型可以从上下文中推断时,可以省略它(仍然需要点),参见 。 +要引用枚举类型的用例,请使用点(`.`)语法,如 `EnumerationType.enumerationCase` 所示。当枚举类型可以从上下文中推断时,可以省略它(仍然需要 `.`),参见 。 -要检查枚举成员的值,请使用 `switch` 语句,如 中所示。枚举类型与 `switch` 语句的 case 块中的枚举成员模式进行模式匹配,参见 。 +要检查枚举用例的值,请使用 `switch` 语句,如 中所示。在 `switch` 语句的用例分支中,枚举类型会与枚举用例进行模式匹配,详见 -枚举的成员可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举成员满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举成员满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与枚举成员的关联值匹配。例如: +枚举的用例可以满足类型成员的协议要求。具体来说,没有任何关联值的枚举用例满足类型 `Self` 的只读类型变量的协议要求,而具有关联值的枚举成员满足返回 `Self` 的函数的协议要求,该函数的参数及其实参标签与枚举成员的关联值匹配。例如: ```swift protocol SomeProtocol { @@ -1774,7 +1774,7 @@ protocol SomeProtocol: AnyObject { 任何从标记为 `AnyObject` 要求的协议继承的协议,也只能被类类型采用。 > 注意: -> 如果一个协议标记了 `objc` 属性,则 `AnyObject` 要求隐式应用于该协议;无需明确将该协议标记为 `AnyObject` 要求。 +> 如果一个协议标记了 `objc` 特性,则 `AnyObject` 要求隐式应用于该协议;无需显式的将该协议标记为 `AnyObject` 要求。 协议是具名类型,因此它们可以出现在代码中与其他具名类型相同的位置,如 中所讨论的。然而,你无法构造协议的实例,因为协议实际上并不提供它们所指定的要求的实现。 @@ -1798,7 +1798,7 @@ protocol SomeProtocol: AnyObject { ### 协议属性声明 -协议声明遵循的类型必须通过在协议声明的主体中包含一个*协议属性声明*来实现一个属性。协议属性声明具有变量声明的特殊形式: +协议通过在协议声明体中包含一个*协议属性声明*,规定遵循该协议的类型必须实现一个属性。协议属性声明是一种特殊形式的变量声明,格式如下: ```swift var <#property name#>: <#type#> { get set } @@ -1806,7 +1806,7 @@ var <#property name#>: <#type#> { get set } 与其他协议成员声明一样,这些属性声明仅声明遵循该协议的类型的 getter 和 setter 要求。因此,你不会在声明它的协议中直接实现 getter 或 setter。 -getter 和 setter 的要求可以通过遵循类型以多种方式满足。如果属性声明同时包含 `get` 和 `set` 关键字,则遵循类型可以通过存储变量属性或可读可写的计算属性来实现(即实现了 getter 和 setter 的属性)。然而,该属性声明不能实现为常量属性或只读计算属性。如果属性声明仅包含 `get` 关键字,则可以实现为任何类型的属性。有关实现协议属性要求的遵循类型的示例,请参见 。 +遵循协议的类型可以通过多种方式满足 getter 和 setter 的要求。如果属性声明同时包含 `get` 和 `set` 关键字,遵循类型可以用存储变量属性或可读写的计算属性(即实现了 getter 和 setter 的属性)来实现。然而,这样的属性声明不能被实现为常量属性或只读计算属性。如果属性声明只包含 `get` 关键字,则可以实现为任何类型的属性。关于符合协议类型如何实现属性要求的示例,参见 。 在协议声明中声明类型属性要求时,使用 `static` 关键字标记属性声明。遵循该协议的结构体和枚举使用 `static` 关键字声明属性,而遵循该协议的类则可以使用 `static` 或 `class` 关键字声明属性。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型属性要求提供默认实现的扩展使用 `static` 关键字。 @@ -1852,7 +1852,7 @@ getter 和 setter 的要求可以通过遵循类型以多种方式满足。如 ### 协议方法声明 -协议声明遵循类型必须通过在协议声明的主体中包含协议方法声明来实现方法。协议方法声明的形式与函数声明相同,有两个例外:它们不包括函数体,并且你不能在函数声明中提供任何默认参数值。有关实现协议方法要求的遵循类型的示例,请参见 。 +协议通过在协议声明体中包含一个协议方法声明,规定遵循该协议的类型必须实现一个方法。协议方法声明的形式与函数声明相同,但有两个例外:它们不包含函数体,且不能在函数声明中提供任何默认参数值。关于遵循协议类型如何实现方法要求的示例,参见 。 在协议声明中声明类或静态方法的要求时,使用 `static` 修饰符标记方法声明。遵循该协议的结构体和枚举使用 `static` 关键字声明该方法,而遵循该协议的类则使用 `static` 或 `class` 关键字声明该方法。为结构体、枚举或类添加协议遵循的扩展使用与其扩展的类型相同的关键字。为类型方法要求提供默认实现的扩展使用 `static` 关键字。 @@ -1870,7 +1870,7 @@ getter 和 setter 的要求可以通过遵循类型以多种方式满足。如 协议通过在协议声明的主体中包含协议构造器声明,要求遵循的类型必须实现一个构造器。协议构造器声明的形式与构造器声明相同,只是不包括构造器的主体。 -一个遵循类型可以通过实现一个非可失败构造器或一个 `init!` 可失败构造器来满足非可失败协议构造器的要求。一个遵循类型可以通过实现任何类型的构造器来满足可失败协议构造器的要求。 +遵循类型可以通过实现一个非可失败构造器或一个 `init!` 可失败构造器来满足非可失败协议构造器的要求。一个遵循类型可以通过实现任何类型的构造器来满足可失败协议构造器的要求。 当一个类实现一个构造器以满足协议的构造器要求时,如果该类尚未标记为 `final` 声明修饰符,则构造器必须标记为 `required` 声明修饰符。 @@ -2058,7 +2058,7 @@ convenience init(<#parameters#>) { > 注意: > 如果你使用 `required` 声明修饰符标记了一个构造器,则在子类中重写所需的构造器时,不要同时使用 `override` 修饰符标记该构造器。 -就像函数和方法一样,构造器可以抛出或重新抛出错误。与函数和方法一样,你在构造器的参数后使用 `throws` 或 `rethrows` 关键字来指示适当的行为。同样,构造器可以是异步的,你使用 `async` 关键字来指示这一点。 +就像函数和方法一样,构造器可以抛出或再抛出错误。与函数和方法一样,你在构造器的参数后使用 `throws` 或 `rethrows` 关键字来指示适当的行为。同样,构造器可以是异步的,你使用 `async` 关键字来指示这一点。 要查看各种类型声明中构造器的示例,请参见 。 @@ -2129,7 +2129,7 @@ if let actualInstance = SomeStruct(input: "Hello") { 初始化失败会通过构造器委托传播。具体来说,如果一个可失败的构造器委托给一个失败并返回 `nil` 的构造器,那么委托的构造器也会失败并隐式返回 `nil`。如果一个不可失败的构造器委托给一个失败并返回 `nil` 的 `init!` 可失败构造器,那么会引发运行时错误(就像你使用`!`运算符来解包一个值为 `nil`的可选值一样)。 -一个可失败的指定构造器可以在子类中被任何类型的指定构造器重写。一个不可失败的指定构造器只能在子类中被不可失败的指定构造器重写。 +可失败的指定构造器可以在子类中被任何类型的指定构造器重写。一个不可失败的指定构造器只能在子类中被不可失败的指定构造器重写。 有关更多信息以及可失败构造器的示例,请参见 。 @@ -2671,7 +2671,7 @@ macro <#name#> = <#macro implementation#> infix operator <#operator name#>: <#precedence group#> ``` -一个*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式 `1 + 2` 中熟悉的加法运算符`+`。 +*中缀运算符*是一个二元运算符,它写在两个操作数之间,例如在表达式 `1 + 2` 中熟悉的加法运算符`+`。 中缀运算符可以选择性地指定优先级组。如果你省略运算符的优先级组,Swift 将使用默认优先级组 `DefaultPrecedence`,该组的优先级仅高于 `TernaryPrecedence`。有关更多信息,请参见 。 From 4bfd33d3921614e3fad02fb6a2d7884318ae9198 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Wed, 16 Oct 2024 13:23:24 +0800 Subject: [PATCH 65/67] feat: proofreading --- .../ReferenceManual/Declarations.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index f2705d6b..4c4a6dc7 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -28,7 +28,7 @@ ## 顶级代码 -Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他具名声明可以被同一模块中每个源文件的代码访问。你可以使用访问级别修饰符来覆盖此默认行为,具体说明见 。 +Swift 源文件中的顶级代码由零个或多个语句、声明和表达式组成。默认情况下,在源文件顶层声明的变量、常量和其他具名声明可以被同一模块中每个源文件的代码访问。你可以使用访问级别修饰符来重写此默认行为,具体说明见 。 有两种类型的顶级代码:顶级声明和可执行的顶级代码。顶级声明仅由声明组成,允许出现在所有 Swift 源文件中。可执行的顶级代码包含语句和表达式,而不仅仅是声明,仅允许作为程序的顶级入口点。 @@ -245,7 +245,7 @@ var <#variable name#>: <#type#> = <#expression#> { 你可以为任何存储属性添加属性观察者。你还可以通过在子类中重写属性,为任何继承自父类的属性(无论是存储的还是计算的)添加属性观察者,参见 。 -构造器*表达式*在类或结构体声明的上下文中是可选的,但在其他地方是必须的。如果能通过构造器*表达式*推断出类型,则*类型*标注是可选的。通常,表达式的类型推断发生在首次读取属性时。如果在读取属性之前,初值已经被覆盖,则推断发生在首次写入属性时。 +构造器*表达式*在类或结构体声明的上下文中是可选的,但在其他地方是必须的。如果能通过构造器*表达式*推断出类型,则*类型*标注是可选的。通常,表达式的类型推断发生在首次读取属性时。如果在读取属性之前,初值已经被重写,则推断发生在首次写入属性时。 -你可以使用以下形式(选其一),覆盖参数标签的默认行为: +你可以使用以下形式(选其一),重写参数标签的默认行为: ```swift <#argument label#> <#parameter name#>: <#parameter type#> @@ -867,7 +867,7 @@ func someFunction(a: borrowing A, b: consuming B) { ... } someFunction(a: someA, b: someB) ``` -明确使用 `borrowing` 或 `consuming` 表示你希望更严格地控制运行时所有权管理的开销。因为复制可能导致意外的运行时所有权操作,所以标记为这两种修饰符的参数在没有使用显式的 `copy` 关键字的情况下不能被复制: +显式使用 `borrowing` 或 `consuming` 表示你希望更严格地控制运行时所有权管理的开销。因为复制可能导致意外的运行时所有权操作,所以标记为这两种修饰符的参数在没有使用显式的 `copy` 关键字的情况下不能被复制: ```swift func borrowingFunction1(a: borrowing A) { @@ -1114,7 +1114,7 @@ func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> 调用抛出函数或方法的必须被包裹在一个 `try` 或 `try!` 表达式中(即,在 `try` 或 `try!` 操作符的作用域内)。 -函数的类型包括它是否会抛出错误以及它抛出的错误类型。这个子类型关系意味着,例如,你可以在需要抛出错误的上下文中使用不抛出错误的函数。有关抛出错误函数类型的更多信息,请参阅 。有关处理具有明确类型的错误的示例,请参阅 。 +函数的类型包括它是否会抛出错误以及它抛出的错误类型。这个子类型关系意味着,例如,你可以在需要抛出错误的上下文中使用不抛出错误的函数。有关抛出错误函数类型的更多信息,请参阅 。有关处理具有显式类型的错误的示例,请参阅 。 你不能仅根据函数是否会抛出错误来重载一个函数。不过,你可以根据函数的*参数*是否会抛出错误来重载函数。 @@ -1200,7 +1200,7 @@ func someFunction(callback: () throws -> Void) rethrows { ``` --> -抛出方法不能覆盖再抛出方法,抛出方法也不能满足再抛出方法的协议要求。也就是说,再抛出方法可以覆盖抛出方法,再抛出方法可以满足抛出方法的协议要求。 +抛出方法不能重写再抛出方法,抛出方法也不能满足再抛出方法的协议要求。也就是说,再抛出方法可以重写抛出方法,再抛出方法可以满足抛出方法的协议要求。 在泛型代码中,抛出特定错误类型是再抛出的替代方案。例如: @@ -2021,11 +2021,11 @@ protocol SubProtocolB: SomeProtocol where SomeType: Equatable { } ## 构造器声明 -*构造器声明*在你的程序中引入了一个类、结构体或枚举的构造器。构造器声明使用 `init` 关键字声明,并有两种基本形式。 +*构造器声明*在你的程序中引入了一个类、结构体或枚举的构造器。构造器声明使用 `init` 关键字声明,有两种基本形式。 -结构体、枚举和类类型可以有任意数量的构造器,但类构造器的规则和相关行为是不同的。与结构体和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,参见 。 +结构体、枚举和类类型可以有任意数量的构造器,但是类的构造器具有不同的规则和行为。与结构体和枚举不同,类有两种类型的构造器:指定构造器和便利构造器,参见 。 -以下形式声明了结构体、枚举和类的指定构造器的构造器: +以下形式声明了结构体和枚举的构造器,以及类的指定构造器:: ```swift init(<#parameters#>) { @@ -2033,9 +2033,9 @@ init(<#parameters#>) { } ``` -类的指定构造器直接初始化类的所有属性。它不能调用同一类的其他构造器,如果该类有一个超类,则必须调用超类的一个指定构造器。如果该类从其超类继承了任何属性,则在当前类中设置或修改这些属性之前,必须调用超类的一个指定构造器。 +类的指定构造器直接初始化类的所有属性。它不能调用当前类的其他构造器,如果该类有一个超类,则必须调用超类的一个指定构造器。如果该类从其超类继承了任何属性,则在当前类中设置或修改这些属性之前,必须调用超类的一个指定构造器。 -只能在类声明的上下文中声明,因此不能通过扩展声明添加到类中。 +指定构造器只能在类声明中声明,因此不能通过扩展声明添加到类中。 结构体和枚举中的构造器可以调用其他已声明的构造器,以委托部分或全部初始化过程。 @@ -2047,7 +2047,7 @@ convenience init(<#parameters#>) { } ``` -便利构造器可以将初始化过程委托给另一个便利构造器或类的某个指定构造器。也就是说,初始化过程必须以调用一个指定构造器结束,该构造器最终初始化类的属性。便利构造器不能调用超类的构造器。 +便利构造器可以将构造过程委托给另一个便利构造器或一个指定构造器。但是,类的构造过程必须以一个将类中所有属性完全初始化的指定构造器的调用作为结束。便利构造器不能调用超类的构造器 你可以使用 `required` 声明修饰符标记指定和便利构造器,以要求每个子类实现该构造器。子类对该构造器的实现也必须标记为 `required` 声明修饰符。 @@ -2129,7 +2129,7 @@ if let actualInstance = SomeStruct(input: "Hello") { 初始化失败会通过构造器委托传播。具体来说,如果一个可失败的构造器委托给一个失败并返回 `nil` 的构造器,那么委托的构造器也会失败并隐式返回 `nil`。如果一个不可失败的构造器委托给一个失败并返回 `nil` 的 `init!` 可失败构造器,那么会引发运行时错误(就像你使用`!`运算符来解包一个值为 `nil`的可选值一样)。 -可失败的指定构造器可以在子类中被任何类型的指定构造器重写。一个不可失败的指定构造器只能在子类中被不可失败的指定构造器重写。 +可失败的指定构造器可以在子类中被任何类型的指定构造器重写。不可失败的指定构造器只能在子类中被不可失败的指定构造器重写。 有关更多信息以及可失败构造器的示例,请参见 。 @@ -2294,12 +2294,12 @@ extension String: TitledLoggable { ``` --> -`Pair` 结构在其泛型类型分别遵循 `Loggable` 或 `TitledLoggable` 时,也会相应地遵循 `Loggable` 和 `TitledLoggable`。在下面的示例中,`oneAndTwo` 是 `Pair` 的一个实例,由于 `String` 遵循 `TitledLoggable`,因此 `oneAndTwo` 也遵循 `TitledLoggable`。当直接调用 `oneAndTwo` 的 `log()` 方法时,将使用包含标题字符串的特定版本。 +`Pair` 结构体在其泛型类型分别遵循 `Loggable` 或 `TitledLoggable` 时,也会相应地遵循 `Loggable` 和 `TitledLoggable`。在下面的示例中,`oneAndTwo` 是 `Pair` 的一个实例,由于 `String` 遵循 `TitledLoggable`,因此 `oneAndTwo` 也遵循 `TitledLoggable`。当直接调用 `oneAndTwo` 的 `log()` 方法时,将使用包含标题字符串的特定版本。 ```swift let oneAndTwo = Pair(first: "one", second: "two") oneAndTwo.log() -// 打印 +// 打印 "Pair of 'String': (one, two)" ``` -在没有扩展明确声明对 `Loggable` 的条件遵循时,其他 `Array` 扩展会隐式创建这些声明,从而导致错误: +在没有扩展显式声明对 `Loggable` 的条件遵循时,其他 `Array` 扩展会隐式创建这些声明,从而导致错误: ```swift extension Array: Loggable where Element: TitledLoggable { } @@ -2596,9 +2596,9 @@ subscript (<#parameters#>) -> <#return type#> { 与计算属性一样,下标声明支持读取和写入所访问元素的值。getter 用于读取值,setter 用于写入值。setter 子句是可选的,当只需要 getter 时,可以省略两个子句,直接返回请求的值。也就是说,如果提供了 setter 子句,则必须同时提供 getter 子句。 -*setter 名称*和括号是可选的。如果你提供了 setter 名称,它将用作 setter 的参数名称。如果你不提供 setter 名称,setter 的默认参数名称是 `value`。setter 的参数类型与*返回类型* 同。 +*setter 名称*和括号是可选的。如果你提供了 setter 名称,它将用作 setter 的参数名称。如果你不提供 setter 名称,setter 的默认参数名称是 `value`。setter 的参数类型与*返回类型*相同。 -你可以在声明它的类型中重载下标声明,只要*参数*或*返回类型*与你正在重载的不同。你还可以覆盖从超类继承的下标声明。当你这样做时,必须使用 `override` 声明修饰符标记被覆盖的下标声明。 +你可以在声明其类型的地方重载下标声明,只要*参数*或*返回类型*与要重载的下标不同。你也可以重写从超类继承的下标声明。在这样做时,必须使用 `override` 声明修饰符标记被重写的下标声明。 下标参数遵循与函数参数相同的规则,但有两个例外。默认情况下,使用下标的参数没有参数标签,这与函数、方法和构造器不同。然而,你可以使用与函数、方法和构造器相同的语法提供显式参数标签。此外,下标不能有 in-out 参数。下标参数可以具有默认值,参见 。 @@ -2681,7 +2681,7 @@ infix operator <#operator name#>: <#precedence group#> prefix operator <#operator name#> ``` -*前缀运算符* 是一种一元运算符,它直接写在操作数之前,例如表达式 `!a` 中的前缀逻辑非运算符(`!`)。 +*前缀运算符*是一种一元运算符,它直接写在操作数之前,例如表达式 `!a` 中的前缀逻辑非运算符(`!`)。 前缀运算符声明不指定优先级。前缀运算符是非结合的。 @@ -2695,7 +2695,7 @@ postfix operator <#operator name#> 与前缀运算符一样,后缀运算符声明不指定优先级。后缀运算符是非结合的。 -声明新运算符后,可以通过声明一个与运算符同名的静态方法来实现它。这个静态方法是运算符参数之一的类型的成员——例如,一个将 `Double` 与 `Int` 相乘的运算符可以在 `Double` 或 `Int` 结构上实现为静态方法。如果你要实现一个前缀或后缀运算符,还必须在方法声明中添加相应的 `prefix` 或 `postfix` 声明修饰符。要查看如何创建和实现新运算符的示例,请参阅 。 +在声明一个新运算符后,你通过声明一个与运算符同名的静态方法来实现它。这个静态方法是运算符作为参数所接受的类型之一的成员——例如,一个将 `Double` 乘以 `Int` 的运算符是作为 `Double` 或 `Int` 结构上的静态方法实现的。如果你在实现前缀或后缀运算符,你还必须在方法声明中标记相应的 `prefix` 或 `postfix` 声明修饰符。要查看如何创建和实现新运算符的示例,请参见 。 > 操作符声明的语法: > @@ -2727,7 +2727,7 @@ precedencegroup <#precedence group name#> { > 注意: > 使用*低级组名称*和*高级组名称*相关联的优先级组必须适合于单一的关系层次结构,但它们*不*必形成线性层次结构。这意味着可以有相对优先级未定义的优先级组。来自这些优先级组的运算符不能在没有分组括号的情况下相互使用。 -Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见 [运算符声明](https://developer.apple.com/documentation/swift/operator_declarations)。 +Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符。例如,加法 (`+`) 和减法 (`-`) 运算符属于 `AdditionPrecedence` 组,而乘法 (`*`) 和除法 (`/`) 运算符属于 `MultiplicationPrecedence` 组。有关 Swift 标准库提供的优先级组的完整列表,请参见[运算符声明](https://developer.apple.com/documentation/swift/operator_declarations)。 运算符的*结合性*指定了在没有分组括号的情况下,具有相同优先级的运算符序列是如何分组的。通过写入上下文敏感的关键字之一来指定运算符的结合性:`left`、`right` 或 `none` ——如果你省略结合性,默认值为 `none`。左结合的运算符从左到右分组。例如,减法运算符(`-`)是左结合的,因此表达式`4 - 5 - 6` 被分组为 `(4 - 5) - 6`,并计算为 `-7`。右结合的运算符从右到左分组,而指定为 `none` 的运算符则完全不结合。相同优先级的非结合运算符不能相邻出现。例如,`<` 运算符的结合性为 `none`,这意味着 `1 < 2 < 3` 不是一个有效的表达式。 @@ -2756,7 +2756,7 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 ## 声明修饰符 -*声明修饰符*是一些关键字或上下文相关的关键字,用于修改声明的行为或含义。你可以通过在声明的属性(如果有的话)和引入声明的关键字之间编写适当的关键字或上下文相关的关键字来指定声明修饰符。 +*声明修饰符* 是用于修改声明行为或意义的关键字或上下文相关关键字。你通过在声明的属性(如果有的话)和引入声明的关键字之间写入相应的关键字或上下文相关关键字来指定声明修饰符。 - `class`:将此修饰符应用于类的成员,以指示该成员是类本身的成员,而不是类实例的成员。具有此修饰符且没有 `final` 修饰符的超类成员可以被子类重写。 @@ -2786,7 +2786,7 @@ Swift 定义了许多优先级组,以配合 Swift 标准库提供的运算符 - `unowned`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,将会引发运行时错误。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 -- `unowned(safe)`:`unowned` 的明确拼写。 +- `unowned(safe)`:`unowned` 的显式拼写。 - `unowned(unsafe)`:将此修饰符应用于存储变量、常量或存储属性,以指示该变量或属性对作为其值存储的对象具有一个无主引用。如果在对象被释放后尝试访问该变量或属性,你将访问对象曾经所在位置的内存,这是一种不安全的内存操作。与弱引用类似,属性或值的类型必须是类类型;与弱引用不同,该类型是非可选的。有关 `unowned` 修饰符的示例和更多信息,请参见 。 From e692cdcd60bd1d038542e35d4d3f5789f3c8a486 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Fri, 18 Oct 2024 10:43:40 +0800 Subject: [PATCH 66/67] fix: per code review --- swift-6-beta.docc/ReferenceManual/Declarations.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index 4c4a6dc7..c0531341 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -799,7 +799,7 @@ func multithreadedFunction(queue: DispatchQueue, x: inout Int) { ``` --> -#### 借用和消耗参数 +#### 借用和消费参数 默认情况下,Swift 使用一套规则在函数调用之间自动管理对象生命周期,在需要时复制值。默认规则旨在在大多数情况下最小化开销——如果你想要更具体的控制,可以应用 `borrowing` 或 `consuming` 参数修饰符。在这种情况下,使用 `copy` 显式标记复制操作。 @@ -812,7 +812,7 @@ and everything else is borrowing. Where are copies implicitly inserted? --> -`borrowing` 修饰符表示函数不会保留参数的值。在这种情况下,调用者保持对对象的所有权,并负责对象的生命周期管理。使用 `borrowing` 可以在函数只临时使用对象时,最大限度地减少开销。 +`borrowing` 修饰函数参数时,函数不会保留参数的值。在这种情况下,调用者保留对象的所有权,并负责对象的生命周期管理。所以当函数只是临时使用对象时,用 `borrowing` 修饰可以最大限度地减少开销。 ```swift // `isLessThan` 不会保留任一参数 @@ -824,7 +824,7 @@ func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { 如果函数需要保留参数的值,例如,通过将其存储在全局变量中——你可以使用 `copy` 显式地复制该值。 ```swift -// 如上所述,但这个 `isLessThan` 还需要记录最小值 +// 同样是 `isLessThan` 函数,这个 `isLessThan` 可以将最小值记录下来 func isLessThan(lhs: borrowing A, rhs: borrowing A) -> Bool { if lhs < storedValue { storedValue = copy lhs @@ -847,7 +847,7 @@ func store(a: consuming A) { 使用 `consuming` 可以在调用者在函数调用后不再需要使用该对象时,最小化开销。 ```swift -// 通常,这是你对一个值执行的最后一件事 +// 通常,这就是最后一次使用 value 了 store(a: value) ``` @@ -855,7 +855,7 @@ store(a: value) ```swift // 编译器会在这里插入一个隐式副本 -store(a: someValue) // 此函数消耗 someValue +store(a: someValue) // 此函数消费 someValue print(someValue) // 这里使用的是 someValue 的副本 ``` @@ -909,7 +909,7 @@ func consumingFunction3(a: consuming A) { ### 特殊类型的参数 -参数可以通过以下形式被忽略、接受可变数量的值,以及提供默认值: +参数可以被忽略,数量可以不固定,还可以为其提供默认值,使用形式如下 ```swift _ : <#parameter type#> From 209be1179692d3cab72bc7c8c0ce9b1a478bbe95 Mon Sep 17 00:00:00 2001 From: Shinolr Date: Mon, 21 Oct 2024 11:03:00 +0800 Subject: [PATCH 67/67] per code review --- swift-6-beta.docc/ReferenceManual/Declarations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift-6-beta.docc/ReferenceManual/Declarations.md b/swift-6-beta.docc/ReferenceManual/Declarations.md index c0531341..242feebc 100644 --- a/swift-6-beta.docc/ReferenceManual/Declarations.md +++ b/swift-6-beta.docc/ReferenceManual/Declarations.md @@ -1114,7 +1114,7 @@ func <#function name#>(<#parameters#>) throws(<#error type#>) -> <#return type#> 调用抛出函数或方法的必须被包裹在一个 `try` 或 `try!` 表达式中(即,在 `try` 或 `try!` 操作符的作用域内)。 -函数的类型包括它是否会抛出错误以及它抛出的错误类型。这个子类型关系意味着,例如,你可以在需要抛出错误的上下文中使用不抛出错误的函数。有关抛出错误函数类型的更多信息,请参阅 。有关处理具有显式类型的错误的示例,请参阅 。 +函数的类型包括:它是否会抛出错误,以及它抛出的错误类型。非抛出函数是抛出函数的子类型。所以,可以在使用抛出函数的地方使用非抛出函数。有关抛出错误函数类型的更多信息,请参阅 。有关处理具有显式类型的错误的示例,请参阅 。 你不能仅根据函数是否会抛出错误来重载一个函数。不过,你可以根据函数的*参数*是否会抛出错误来重载函数。