replace all _ with -

This commit is contained in:
Jie Liang
2019-04-02 09:47:36 -05:00
parent 5d3bf7bbcf
commit 3201f23a17
37 changed files with 488 additions and 488 deletions

View File

@ -4,7 +4,7 @@
泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的。实际上,即使你没有意识到,你也一直在*语言指南*中使用泛型。例如Swift 的 `Array``Dictionary` 都是泛型集合。你可以创建一个 `Int` 类型数组,也可创建一个 `String` 类型数组,甚至可以是任意其他 Swift 类型的数组。同样,你也可以创建一个存储任意指定类型的字典,并对该类型没有限制。
## 泛型解决的问题 {#the_problem_that_generics_solve}
## 泛型解决的问题 {#the-problem-that-generics-solve}
下面是一个标准的非泛型函数 `swapTwoInts(_:_:)`,用来交换两个 `Int` 值:
@ -52,7 +52,7 @@ func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
>
> 在上面三个函数中,`a` 和 `b` 类型必须相同。如果 `a` 和 `b` 类型不同那它们俩就不能互换值。Swift 是类型安全的语言,所以它不允许一个 `String` 类型的变量和一个 `Double` 类型的变量互换值。试图这样做将导致编译错误。
## 泛型函数 {#generic_functions}
## 泛型函数 {#generic-functions}
泛型函数可适用于任意类型,下面是函数 `swapTwoInts(_:_:)` 的泛型版本,命名为 `swapTwoValues(_:_:)`
@ -95,7 +95,7 @@ swapTwoValues(&someString, &anotherString)
>
> 上面定义的 `swapTwoValues(_:_:)` 函数是受 `swap(_:_:)` 函数启发而实现的。后者存在于 Swift 标准库,你可以在你的应用程序中使用它。如果你在代码中需要类似 `swapTwoValues(_:_:)` 函数的功能,你可以使用已存在的 `swap(_:_:)` 函数。
## 类型参数 {#type_parameters}
## 类型参数 {#type-parameters}
上面 `swapTwoValues(_:_:)` 例子中,占位类型 `T` 是一个类型参数的例子,类型参数指定并命名一个占位类型,并且紧随在函数名后面,使用一对尖括号括起来(例如 `<T>`)。
@ -103,7 +103,7 @@ swapTwoValues(&someString, &anotherString)
你可提供多个类型参数,将它们都写在尖括号中,用逗号分开。
## 命名类型参数 {#naming_type_parameters}
## 命名类型参数 {#naming-type-parameters}
大多情况下,类型参数具有描述下的名称,例如字典 `Dictionary<Key, Value>` 中的 `Key``Value` 及数组 `Array<Element>` 中的 `Element`,这能告诉阅读代码的人这些参数类型与泛型类型或函数之间的关系。然而,当它们之间没有有意义的关系时,通常使用单个字符来表示,例如 `T``U``V`,例如上面演示函数 `swapTwoValues(_:_:)` 中的 `T`
@ -111,7 +111,7 @@ swapTwoValues(&someString, &anotherString)
>
> 请始终使用大写字母开头的驼峰命名法(例如 `T` 和 `MyTypeParameter`)来为类型参数命名,以表明它们是占位类型,而不是一个值。
## 泛型类型 {#generic_types}
## 泛型类型 {#generic-types}
除了泛型函数Swift 还允许自定义*泛型类型*。这些自定义类、结构体和枚举可以适用于*任意类型*,类似于 `Array``Dictionary`
@ -199,7 +199,7 @@ let fromTheTop = stackOfStrings.pop()
![](https://docs.swift.org/swift-book/_images/stackPoppedOneString_2x.png)
## 泛型扩展 {#extending_a_generic_type}
## 泛型扩展 {#extending-a-generic-type}
当对泛型类型进行扩展时,你并不需要提供类型参数列表作为定义的一部分。原始类型定义中声明的类型参数列表在扩展中可以直接使用,并且这些来自原始类型中的参数名称会被用作原始定义中类型参数的引用。
@ -226,7 +226,7 @@ if let topItem = stackOfStrings.topItem {
// 打印“The top item on the stack is tres.”
```
## 类型约束 {#type_constraints}
## 类型约束 {#type-constraints}
`swapTwoValues(_:_:)` 函数和 `Stack` 适用于任意类型。不过,如果能对泛型函数或泛型类型中添加特定的*类型约束*,这将在某些情况下非常有用。类型约束指定类型参数必须继承自指定类、遵循特定的协议或协议组合。
@ -236,7 +236,7 @@ if let topItem = stackOfStrings.topItem {
当自定义泛型类型时,你可以定义你自己的类型约束,这些约束将提供更为强大的泛型编程能力。像 `可哈希hashable` 这种抽象概念根据它们的概念特征来描述类型,而不是它们的具体类型。
### 类型约束语法 {#type_constraint_syntax}
### 类型约束语法 {#type-constraint-syntax}
在一个类型参数名后面放置一个类名或者协议名,并用冒号进行分隔,来定义类型约束。下面将展示泛型函数约束的基本语法(与泛型类型的语法相同):
@ -248,7 +248,7 @@ func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
上面这个函数有两个类型参数。第一个类型参数 `T` 必须是 `SomeClass` 子类;第二个类型参数 `U` 必须符合 `SomeProtocol` 协议。
### 类型约束实践 {#type_constraints_in_action}
### 类型约束实践 {#type-constraints-in-action}
这里有个名为 `findIndex(ofString:in:)` 的非泛型函数,该函数的功能是在一个 `String` 数组中查找给定 `String` 值的索引。若查找到匹配的字符串,`findIndex(ofString:in:)` 函数返回该字符串在数组中的索引值,否则返回 `nil`
@ -316,11 +316,11 @@ let stringIndex = findIndex(of: "Andrea", in: ["Mike", "Malcolm", "Andrea"])
// stringIndex 类型为 Int?,其值为 2
```
## 关联类型 {#associated_types}
## 关联类型 {#associated-types}
定义一个协议时,声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了一个占位符名称,其代表的实际类型在协议被遵循时才会被指定。关联类型通过 `associatedtype` 关键字来指定。
### 关联类型实践 {#associated_types_in_action}
### 关联类型实践 {#associated-types-in-action}
下面例子定义了一个 `Container` 协议,该协议定义了一个关联类型 `Item`
@ -406,7 +406,7 @@ struct Stack<Element>: Container {
这一次,占位类型参数 `Element` 被用作 `append(_:)` 方法的 `item` 参数和下标的返回类型。Swift 可以据此推断出 `Element` 的类型即是 `Item` 的类型。
### 扩展现有类型来指定关联类型 {#extending_an_existing_type_to_specify_an_associated_type}
### 扩展现有类型来指定关联类型 {#extending-an-existing-type-to-specify-an-associated-type}
[在扩展添加协议一致性](./21_Protocols.md#adding_protocol_conformance_with_an_extension)中描述了如何利用扩展让一个已存在的类型符合一个协议,这包括使用了关联类型协议。
@ -418,7 +418,7 @@ extension Array: Container {}
`Array``append(_:)` 方法和下标确保了 Swift 可以推断出 `Item` 具体类型。定义了这个扩展后,你可以将任意 `Array` 当作 Container 来使用。
### 给关联类型添加约束 {#adding_constraints_to_an_associated_type}
### 给关联类型添加约束 {#adding-constraints-to-an-associated-type}
你可以在协议里给关联类型添加约束来要求遵循的类型满足约束。例如,下面的代码定义了 `Container` 协议, 要求关联类型 `Item` 必须遵循 `Equatable` 协议:
@ -433,7 +433,7 @@ protocol Container {
要遵守 `Container` 协议,`Item` 类型也必须遵守 `Equatable` 协议。
### 在关联类型约束里使用协议 {#using_a_protocol_in_its_associated_types_constraints}
### 在关联类型约束里使用协议 {#using-a-protocol-in-its-associated-types-constraints}
协议可以作为它自身的要求出现。例如,有一个协议细化了 `Container` 协议,添加了一个` suffix(_:)` 方法。`suffix(_:)` 方法返回容器中从后往前给定数量的元素,并把它们存储在一个 `Suffix` 类型的实例里。
@ -482,7 +482,7 @@ extension IntStack: SuffixableContainer {
}
```
## 泛型 Where 语句 {#where_clauses}
## 泛型 Where 语句 {#where-clauses}
[类型约束](#type_constraints)让你能够为泛型函数、下标、类型的类型参数定义一些强制要求。
@ -562,7 +562,7 @@ if allItemsMatch(stackOfStrings, arrayOfStrings) {
上面的例子创建 `Stack` 实例来存储 `String` 值,然后将三个字符串压栈。这个例子还通过数组字面量创建了一个 `Array` 实例,数组中包含同栈中一样的三个字符串。即使栈和数组是不同的类型,但它们都遵从 `Container` 协议,而且它们都包含相同类型的值。因此你可以用这两个容器作为参数来调用 `allItemsMatch(_:_:)` 函数。在上面的例子中,`allItemsMatch(_:_:)` 函数正确地显示了这两个容器中的所有元素都是相互匹配的。
## 具有泛型 Where 子句的扩展 {#extensions_with_a_generic_where_clause}
## 具有泛型 Where 子句的扩展 {#extensions-with-a-generic-where-clause}
你也可以使用泛型 `where` 子句作为扩展的一部分。基于以前的例子,下面的示例扩展了泛型 `Stack` 结构体,添加一个 `isTop(_:)` 方法。
@ -641,7 +641,7 @@ print([1260.0, 1200.0, 98.6, 37.0].average())
就像可以在其他地方写泛型 `where` 子句一样,你可以在一个泛型 `where` 子句中包含多个条件作为扩展的一部分。用逗号分隔列表中的每个条件。
## 具有泛型 Where 子句的关联类型 {#associated_types_with_a_generic_where_clause}
## 具有泛型 Where 子句的关联类型 {#associated-types-with-a-generic-where-clause}
你可以在关联类型后面加上具有泛型 `where` 的字句。例如,建立一个包含迭代器(`Iterator`)的容器,就像是标准库中使用的 `Sequence` 协议那样。你应该这么写:
@ -665,7 +665,7 @@ protocol Container {
protocol ComparableContainer: Container where Item: Comparable { }
```
## 泛型下标 {#generic_subscripts}
## 泛型下标 {#generic-subscripts}
下标可以是泛型,它们能够包含泛型 `where` 子句。你可以在 `subscript` 后用尖括号来写占位符类型,你还可以在下标代码块花括号前写 `where` 子句。例如: