更新部分内容到 Swift 5.7 (#1200)

* 更新内容到 Swift 5.7

* 更新内容到 Swift 5.7

* 更新内容到 Swift 5.7

* update to Swift version 5.7

* 更新内容到 Swift 5.7

* 更新内容到 Swift 5.7

* 修正部分术语

* 更新内容到 Swift 5.7

* 更新内容到 Swift 5.7

* 标题格式修改

* 修改了部分用词

* 修改了代码块格式

* 修改了代码段及行内代码格式

* 修改了代码段及行内代码样式

* 按照排版要求重新修改了部分格式

* Delete 02_Lexical_Structure.md

* Delete 03_Types.md

* Delete 04_Expressions.md

* Delete 05_Statements.md

* Delete 07_Attributes.md

* Delete 10_Summary_of_the_Grammar.md

* 根据排版指南修改了部分格式

* 根据排版指南修改了部分格式

* Update source/03_language_reference/02_Lexical_Structure.md

Co-authored-by: Jie Liang <lj925184928@gmail.com>
This commit is contained in:
Robortsystem
2022-09-10 21:00:58 +08:00
committed by GitHub
parent df35244821
commit 77b5caff91
20 changed files with 1092 additions and 723 deletions

View File

@ -1,13 +1,13 @@
# 表达式Expressions
Swift 中存在四种表达式:前缀表达式,二元表达式,基本表达式和后缀表达式。表达式在返回一个值的同时还可以引发副作用。
Swift 中存在四种表达式:前缀表达式,中缀表达式,基本表达式和后缀表达式。表达式在返回一个值的同时还可以引发副作用。
通过前缀表达式和二元表达式可以对简单表达式使用各种运算符。基本表达式从概念上讲是最简单的一种表达式,它是一种访问值的方式。后缀表达式则允许你建立复杂的表达式,例如函数调用和成员访问。每种表达式都在下面有详细论述。
通过前缀表达式和中缀表达式可以对简单表达式使用各种运算符。基本表达式从概念上讲是最简单的一种表达式,它是一种访问值的方式。后缀表达式则允许你建立复杂的表达式,例如函数调用和成员访问。每种表达式都在下面有详细论述。
> 表达式语法
#### expression {#expression}
> *表达式* → [try 运算符](#try-operator)<sub>可选</sub> [await 运算符](#await-operator)<sub>可选</sub> [前缀表达式](#prefix-expression) [二元表达式列表](#binary-expressions)<sub>可选</sub>
> *表达式* → [try 运算符](#try-operator)<sub>可选</sub> [await 运算符](#await-operator)<sub>可选</sub> [前缀表达式](#prefix-expression) [中缀表达式列表](#infix-expressions)<sub>可选</sub>
#### expression-list {#expression-list}
@ -62,7 +62,7 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
强制 try 表达式的返回值是该*表达式*的值。如果该*表达式*抛出了错误,将会引发运行时错误。
二元运算符左侧的表达式被标记上 `try``try?` 或者 `try!` 时,这个运算符对整个二元表达式都产生作用。也就是说,你可以使用括号来明确运算符的作用范围。
中缀运算符左侧的表达式被标记上 `try``try?` 或者 `try!` 时,这个运算符对整个中缀表达式都产生作用。也就是说,你可以使用括号来明确运算符的作用范围。
```swift
// try 对两个函数调用都产生作用
@ -75,7 +75,7 @@ sum = try (someThrowingFunction() + anotherThrowingFunction())
sum = (try someThrowingFunction()) + anotherThrowingFunction()
```
`try` 表达式不能出现在二元运算符的的右侧,除非二元运算符是赋值运算符或者 `try` 表达式是被圆括号括起来的。
`try` 表达式不能出现在中缀运算符的的右侧,除非中缀运算符是赋值运算符或者 `try` 表达式是被圆括号括起来的。
如果表达式中同时包含 `try``await` 运算符,`try` 运算符必须在前面。
@ -99,7 +99,7 @@ sum = (try someThrowingFunction()) + anotherThrowingFunction()
`await` 表达式只能在异步的上下文中出现,比如传入 `async(priority:operation:)` 函数的尾随闭包中。它不能在 `defer` 语句的闭包中,或者在同步函数的自动闭包中出现。
二元运算符左侧的表达式被标记上 `await` 运算符时,这个运算符对整个二元表达式都产生作用。也就是说,你可以使用括号来明确运算符的作用范围。
中缀运算符左侧的表达式被标记上 `await` 运算符时,这个运算符对整个中缀表达式都产生作用。也就是说,你可以使用括号来明确运算符的作用范围。
```swift
// await 对两个函数调用都产生作用
@ -112,7 +112,7 @@ sum = await (someAsyncFunction() + anotherAsyncFunction())
sum = (await someAsyncFunction()) + anotherAsyncFunction()
```
`await` 表达式不能出现在二元运算符的的右侧,除非二元运算符是赋值运算符或者 `await` 表达式是被圆括号括起来的。
`await` 表达式不能出现在中缀运算符的的右侧,除非中缀运算符是赋值运算符或者 `await` 表达式是被圆括号括起来的。
如果表达式中同时包含 `try``await` 运算符,`try` 运算符必须在前面。
@ -122,11 +122,11 @@ sum = (await someAsyncFunction()) + anotherAsyncFunction()
> *await 运算符* → **await**
## 二元表达式 {#binary-expressions}
## 中缀表达式 {#infix-expressions}
*二元表达式*由中缀运算符和左右参数表达式组成。形式如下:
*中缀表达式*由中缀运算符和左右参数表达式组成。形式如下:
> `左侧参数` `二元运算符` `右侧参数`
> `左侧参数` `中缀运算符` `右侧参数`
关于这些运算符的更多信息,请参阅 [基本运算符](../02_language_guide/02_Basic_Operators.md) 和 [高级运算符](../02_language_guide/27_Advanced_Operators.md)。
@ -134,22 +134,22 @@ sum = (await someAsyncFunction()) + anotherAsyncFunction()
> 注意
>
> 在解析时,一个二元表达式将作为一个扁平列表表示,然后根据运算符的优先级,再进一步进行组合。例如,`2 + 3 * 5` 首先被看作具有五个元素的列表,即 `2`、`+`、`3`、`*`、`5`,随后根据运算符优先级组合为 `(2 + (3 * 5))`。
> 在解析时,一个中缀表达式将作为一个扁平列表表示,然后根据运算符的优先级,再进一步进行组合。例如,`2 + 3 * 5` 首先被看作具有五个元素的列表,即 `2`、`+`、`3`、`*`、`5`,随后根据运算符优先级组合为 `(2 + (3 * 5))`。
#### binary-expression {#binary-expression}
> 二元表达式语法
#### infix-expression {#infix-expression}
> 中置表达式语法
>
> *二元表达式* → [二元运算符](./02_Lexical_Structure.md#binary-operator) [前缀表达式](#prefix-expression)
> *中置表达式* → [中置运算符](./02_Lexical_Structure.md#infix-operator) [前缀表达式](#prefix-expression)
>
> *二元表达式* → [赋值运算符](#assignment-operator) [try 运算符](#try-operator)<sub>可选</sub> [前缀表达式](#prefix-expression)
> *中置表达式* → [赋值运算符](#assignment-operator) [try 运算符](#try-operator)<sub>可选</sub> [前缀表达式](#prefix-expression)
>
> *二元表达式* → [条件运算符](#conditional-operator) [try 运算符](#try-operator)<sub>可选</sub> [前缀表达式](#prefix-expression)
> *中置表达式* → [条件运算符](#conditional-operator) [try 运算符](#try-operator)<sub>可选</sub> [前缀表达式](#prefix-expression)
>
> *二元表达式* → [类型转换运算符](#type-casting-operator)
> *中置表达式* → [类型转换运算符](#type-casting-operator)
#### binary-expressions {#binary-expressions}
> *二元表达式列表* → [二元表达式](#binary-expression) [二元表达式列表](#binary-expressions)<sub>可选</sub>
#### infix-expressions {#infix-expressions}
> *中置表达式列表* → [中置表达式](#infix-expression) [中置表达式列表](#infix-expressions)<sub>可选</sub>
### 赋值表达式 {#assignment-operator}
赋值表达式会为某个给定的表达式赋值,形式如下;
@ -235,7 +235,7 @@ f(x as Any)
> *类型转换运算符* → **as** **!** [类型](./03_Types.md#type)
## 基本表达式 {#primary-expressions}
*基本表达式*是最基本的表达式。它们可以单独使用,也可以跟前缀表达式、二元表达式、后缀表达式组合使用。
*基本表达式*是最基本的表达式。它们可以单独使用,也可以跟前缀表达式、中置表达式、后缀表达式组合使用。
> 基本表达式语法
@ -461,6 +461,16 @@ struct Point {
闭包的参数声明形式跟函数一样,请参阅 [函数声明](./06_Declarations.md#function-declaration)。
在闭包表达式中写入 `throws``async` 将显式地将闭包标记为丢掷或异步的。
```swift
{ (parameters) async throws -> return type in
statements
}
```
如果闭包的主体中含有 try 表达式,则认为该闭包会引发异常。同理,若闭包主体含有 await 表达式,则认为该闭包是异步的。
闭包还有几种特殊的形式,能让闭包使用起来更加简洁:
- 闭包可以省略它的参数和返回值的类型。如果省略了参数名和所有的类型,也要省略 `in` 关键字。如果被省略的类型无法被编译器推断,那么就会导致编译错误。
@ -555,11 +565,11 @@ myFunction { [weak parent = self.parent] in print(parent!.title) }
>
> #### closure-expression {#closure-expression}
>
> *闭包表达式* → **{** [闭包签名](#closure-signature)<sub>可选</sub> [语句](#statements) **}**
> *闭包表达式* → **{** [特性](#attribute)<sub>可选</sub> [闭包签名](#closure-signature)<sub>可选</sub> [语句](#statements) **}**
>
> #### closure-signature {#closure-signature}
>
> *闭包签名* → [捕获列表](#capture-list)<sub>可选</sub> [闭包形参子句](#closure-parameter-clause) **throws**<sub>可选</sub> [函数结果](./06_Declarations.md#function-result)<sub>可选</sub> **in**
> *闭包签名* → [捕获列表](#capture-list)<sub>可选</sub> [闭包形参子句](#closure-parameter-clause) **async**<sub>可选</sub> **throws**<sub>可选</sub> [函数结果](./06_Declarations.md#function-result)<sub>可选</sub> **in**
>
> *闭包签名* → [捕获列表](#capture-list) **in**
>
@ -1255,6 +1265,23 @@ let x = [10, 3, 20, 15, 4]
.map { $0 * 100 }
```
你可以将这种多行链式语法与编译器控制语句结合,以控制调用每个方法的时间。例如,以下代码在 iOS 上应用了不同的过滤规则:
```swift
let numbers = [10, 20, 33, 43, 50]
#if os(iOS)
.filter { $0 < 40}
#else
.filter {$0 > 25}
#endif
```
`#if``#endif` 和其它编译指令之间的条件编译块可以包含一个隐式成员表达式,后跟零个或多个后缀,以形成一个后缀表达式。这些条件编译块还可以包含另一个条件编译块,或者这些表达式和块的组合体。
除了顶级代码top-level code以外你还可以在任何能编写显式成员表达式的地方使用上述语法。
在条件编译块中,编译指令 `#if` 的分支必须包含至少一个表达式,其它分支可以为空。
> 显式成员表达式语法
#### explicit-member-expression {#explicit-member-expression}
@ -1262,7 +1289,9 @@ let x = [10, 3, 20, 15, 4]
>
> *显式成员表达式* → [后缀表达式](#postfix-expression) **.** [标识符](./02_Lexical_Structure.md#identifier) [泛型实参子句](./09_Generic_Parameters_and_Arguments.md#generic-argument-clause)<sub>可选</sub><br/>
>
> *显式成员表达式* → [后缀表达式](#postfix-expression) **.** [标识符](./02_Lexical_Structure.md#identifier) **(** [参数名称](#argument-names) **)**
> *显式成员表达式* → [后缀表达式](#postfix-expression) **.** [标识符](./02_Lexical_Structure.md#identifier) **(** [参数名称](#argument-names) **)**
> *显示成员表达式* → [后缀表达式](#postfix-expression) [条件编译块](#conditional-compilation-block)
#### argument-names {#argument-names}
> *参数名称* → [参数名](#argument-name) [参数名称](#argument-names)<sub>可选</sub><br/>