expressions Swift 5.3 beta
This commit is contained in:
@ -9,7 +9,6 @@ Swift 中存在四种表达式:前缀表达式,二元表达式,基本表
|
||||
|
||||
#### expression {#expression}
|
||||
> *表达式* → [try 运算符](#try-operator)<sub>可选</sub> [前缀表达式](#prefix-expression) [二元表达式列表](#binary-expressions)<sub>可选</sub>
|
||||
>
|
||||
|
||||
#### expression-list {#expression-list}
|
||||
|
||||
@ -232,11 +231,18 @@ f(x as Any)
|
||||
|
||||
字面量 | 类型 | 值
|
||||
:------------- | :---------- | :----------
|
||||
`#file` | `String` | 所在的文件名
|
||||
`#file` | `String` | 所在的文件名及模块
|
||||
`#filePath` | `String` | 所在的文件路径
|
||||
`#line` | `Int` | 所在的行数
|
||||
`#column` | `Int` | 所在的列数
|
||||
`#function` | `String` | 所在的声明的名字
|
||||
`#dsohandle` | `UnsafeRawPointer` | 所使用的 DSO(动态共享对象)句柄
|
||||
|
||||
`#file` 表达式的值的格式是 *module*/*file*,*file* 是表达式所在的文件名,*module* 是文件所所在的模块名。`#filePath` 表达式的字符串值是表达式所在的文件在整个文件系统里的路径。所有这些值可以被 `#sourceLocation` 改变,详见 [行控制语句](./05_Statements.md#line-control-statements)。
|
||||
|
||||
> 注意
|
||||
>
|
||||
> 要解析 `#file` 表达式,第一个斜杠(/)之前的文本作为模块名,最后一个斜杠之后的文本作为文件名。将来,该字符串可能包含多个斜杠,例如 `MyModule/some/disambiguation/MyFile.swift`。
|
||||
|
||||
对于 `#function`,在函数中会返回当前函数的名字,在方法中会返回当前方法的名字,在属性的存取器中会返回属性的名字,在特殊的成员如 `init` 或 `subscript` 中会返回这个关键字的名字,在某个文件中会返回当前模块的名字。
|
||||
|
||||
@ -288,7 +294,7 @@ Xcode 使用 playground 字面量对程序编辑器中的颜色、文件或者
|
||||
>
|
||||
> *字面量表达式* → [数组字面量](#array-literal) | [字典字面量](#dictionary-literal) | [练习场字面量](#playground-literal)
|
||||
>
|
||||
> *字面量表达式* → **#file** | **#line** | **#column** | **#function**
|
||||
> *字面量表达式* → **#file** | **#filePath** | **#line** | **#column** | **#function**
|
||||
>
|
||||
|
||||
|
||||
@ -757,7 +763,7 @@ print(count as Any)
|
||||
// 打印 "Optional(5)"
|
||||
```
|
||||
|
||||
可以混合使用各种 key-path 组件来访问一些深度嵌套类型的值。下面的代码通过组合不同的组件,使用 key-path 表达式访问了一个字典数组中不同的值和属性。
|
||||
可以混合使用各种 key path 组件来访问一些深度嵌套类型的值。下面的代码通过组合不同的组件,使用 key-path 表达式访问了一个字典数组中不同的值和属性。
|
||||
|
||||
```swift
|
||||
let interestingNumbers = ["prime": [2, 3, 5, 7, 11, 13, 17],
|
||||
@ -773,6 +779,39 @@ print(interestingNumbers[keyPath: \[String: [Int]].["hexagonal"]!.count.bitWidth
|
||||
// 打印 "64"
|
||||
```
|
||||
|
||||
你可以在平时提供函数或者闭包的上下文里使用 key path 表达式。特别地,你可以用根类型是 `SomeType` 和路径产生 `Value` 类型值的 key path 表达式来替换类型是 `(SomeType) -> Value` 的函数或者闭包。
|
||||
|
||||
```swift
|
||||
truct Task {
|
||||
var description: String
|
||||
var completed: Bool
|
||||
}
|
||||
var toDoList = [
|
||||
Task(description: "Practice ping-pong.", completed: false),
|
||||
Task(description: "Buy a pirate costume.", completed: true),
|
||||
Task(description: "Visit Boston in the Fall.", completed: false),
|
||||
]
|
||||
|
||||
// 下面两种写法是等价的。
|
||||
let descriptions = toDoList.filter(\.completed).map(\.description)
|
||||
let descriptions2 = toDoList.filter { $0.completed }.map { $0.description }
|
||||
```
|
||||
|
||||
任何 key path 表达式的副作用发生的关键在于表达式在哪里被执行。例如,如果你在 key path 表达式中的一个下标里使用函数调用,该函数只会在表达式计算的时候调用一次,而不是每次这个 key path 被使用的时候。
|
||||
|
||||
```swift
|
||||
func makeIndex() -> Int {
|
||||
print("Made an index")
|
||||
return 0
|
||||
}
|
||||
// 下面这行调用 makeIndex()。
|
||||
let taskKeyPath = \[Task][makeIndex()]
|
||||
// 打印 "Made an index"
|
||||
|
||||
// 使用 taskKeyPath 不会再次调用 makeIndex()。
|
||||
let someTask = toDoList[keyPath: taskKeyPath]
|
||||
```
|
||||
|
||||
关于更多如何使用 key path 与 Objective-C APIs 交互的信息,请参阅 [在 Swift 中使用 Objective-C 运行时特性](https://developer.apple.com/documentation/swift/using_objective_c_runtime_features_in_swift)。关于更多 key-value 编程和 key-value 观察的信息,请参阅 [Key-Value 编程](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/KeyValueCoding/index.html#//apple-ref/doc/uid/10000107i) 和 [Key-Value 观察编程](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple-ref/doc/uid/10000177i)。
|
||||
|
||||
> key-path 表达式语法
|
||||
@ -959,14 +998,17 @@ print(keyPath == c.getSomeKeyPath())
|
||||
如果函数声明中指定了参数的名字,那么在调用的时候也必须得写出来。这种函数调用表达式具有以下形式:
|
||||
|
||||
> `函数名`(`参数名 1`: `参数 1`, `参数名 2`: `参数 2`)
|
||||
>
|
||||
|
||||
如果函数的最后一个参数是函数类型,可以在函数调用表达式的尾部(右圆括号之后)加上一个闭包,该闭包会作为函数的最后一个参数。如下两种写法是等价的:
|
||||
|
||||
```swift
|
||||
// someFunction 接受整数和闭包参数
|
||||
// someFunction 接受整型和闭包的实参
|
||||
someFunction(x, f: {$0 == 13})
|
||||
someFunction(x) {$0 == 13}
|
||||
|
||||
// anotherFunction 接受一个整型和两个闭包的实参
|
||||
anotherFunction(x: x, f: { $0 == 13 }, g: { print(99) })
|
||||
anotherFunction(x: x) { $0 == 13 } g: { print(99) }
|
||||
```
|
||||
|
||||
如果闭包是该函数的唯一参数,那么圆括号可以省略。
|
||||
@ -988,30 +1030,32 @@ myData.someMethod {$0 == 13}
|
||||
>
|
||||
> *函数调用表达式* → [后缀表达式](#postfix-expression) [函数调用参数子句](#function-call-argument-clause)<sub>可选</sub> [尾随闭包](#trailing-closure)
|
||||
>
|
||||
>#### function-call-argument-clause {#function-call-argument-clause}
|
||||
>
|
||||
>
|
||||
#### function-call-argument-clause {#function-call-argument-clause}
|
||||
>
|
||||
> *函数调用参数子句* → **(** **)** | **(** [函数调用参数表](#function-call-argument-list) **)**
|
||||
>
|
||||
>
|
||||
#### function-call-argument-list {#function-call-argument-list}
|
||||
> #### function-call-argument-list {#function-call-argument-list}
|
||||
>
|
||||
> *函数调用参数表* → [函数调用参数](#function-call-argument) | [函数调用参数](#function-call-argument) **,** [*函数调用参数表*](#function-call-argument-list)
|
||||
>
|
||||
>
|
||||
#### function-call-argument {#function-call-argument}
|
||||
> #### function-call-argument {#function-call-argument}
|
||||
>
|
||||
> *函数调用参数* → [表达式](#expression) | [标识符](02-Lexical-Structure.md#identifier) **:** [表达式](#expression)
|
||||
>
|
||||
> *函数调用参数* → [运算符](./02_Lexical_Structure.md#operator) | [标识符](./02-Lexical-Structure.md#identifier) **:** [运算符](./02-Lexical-Structure.md#operator)
|
||||
>
|
||||
>
|
||||
>
|
||||
#### trailing-closure {#trailing-closure}
|
||||
> #### trailing-closure {#trailing-closure}
|
||||
>
|
||||
> *尾随闭包* → [闭包表达式](#closure-expression)
|
||||
>
|
||||
> #### labeled-trailing-closures {#labeled-trailing-closures}
|
||||
>
|
||||
> *标签尾随闭包集* → [标签尾随闭包](#labeled-trailing-closure) [标签尾随闭包集](#labeled-trailing-closures)<sub>可选</sub>
|
||||
>
|
||||
> #### labeled-trailing-closure {#labeled-trailing-closure}
|
||||
> *标签尾随闭包* → [标识符](./02-Lexical-Structure.md#identifier) **:** [闭包表达式](#closure-expression)
|
||||
|
||||
|
||||
### 构造器表达式 {#initializer-expression}
|
||||
*构造器表达式*用于访问某个类型的构造器,形式如下:
|
||||
|
||||
Reference in New Issue
Block a user