具有泛型 Where 子句的关联类型

泛型下标
This commit is contained in:
mynightelfplayer@hotmail.com
2017-09-01 11:47:47 +08:00
parent a104f980b4
commit 2db98b316e

View File

@ -31,6 +31,8 @@
- [关联类型](#associated_types)
- [泛型 Where 语句](#where_clauses)
- [具有泛型 where 子句的扩展](#extensions_with_a_generic_where_clause)
- [具有泛型 Where 子句的关联类型](#associated_types_with_a_generic_where_clause)
- [泛型下标](#generic_subscripts)
*泛型代码*让你能够根据自定义的需求,编写出适用于任意类型、灵活可重用的函数及类型。它能让你避免代码的重复,用一种清晰和抽象的方式来表达代码的意图。
@ -618,4 +620,56 @@ print([1260.0, 1200.0, 98.6, 37.0].average())
此示例将一个 `average()` 方法添加到 `Item` 类型为 `Double` 的容器中。此方法遍历容器中的元素将其累加,并除以容器的数量计算平均值。它将数量从 `Int` 转换为 `Double` 确保能够进行浮点除法。
就像可以在其他地方写泛型 `where` 子句一样,你可以在一个泛型 `where` 子句中包含多个条件作为扩展的一部分。用逗号分隔列表中的每个条件。
就像可以在其他地方写泛型 `where` 子句一样,你可以在一个泛型 `where` 子句中包含多个条件作为扩展的一部分。用逗号分隔列表中的每个条件。
<a name="associated_types_with_a_generic_where_clause"></a>
## 具有泛型 Where 子句的关联类型
你能够包含一个具有泛型 Where 子句的关联类型。例如建立一个包含迭代器Iterator的容器就像是标准库中使用的Sequence协议那样。下面是你所写的代码
```swift
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
associatedtype Iterator: IteratorProtocol where Iterator.Element == Item
func makeIterator() -> Iterator
}
```
迭代器Iterator的泛型Where子句要求无论迭代器是什么类型迭代器中的元素类型必须和容器项目的类型保持一致。makeIterator()则提供了容器的迭代器的访问接口。
一个协议继承了另一个协议你通过在协议声明的时候包含泛型Where子句来添加了一个约束到被继承协议的关联类型。例如下面的代码声明了一个ComparableContainer协议它要求所有的Item必须是Comparable的。
```swift
protocol ComparableContainer: Container where Item: Comparable { }
```
<a name="generic_subscripts"></a>
##泛型下标
下标能够是泛型的他们能够包含泛型Where子句。你可以在subscript后面的尖括号中写下占位符placeholder类型名称在下标代码体开始的标志的花括号之前写下泛型Where子句。例如
```swift
extension Container {
subscript<Indices: Sequence>(indices: Indices) -> [Item]
where Indices.Iterator.Element == Int {
var result = [Item]()
for index in indices {
result.append(self[index])
}
return result
}
}
```
这个Container协议的扩展添加了一个下标下标是一个序列的索引返回的则是索引所在的项目的值所构成的数组。这个泛型下标的约束如下
- 在尖括号中的泛型参数Indices必须是符合标准库中的Sequence协议的类型。
- 下标使用的单一的参数indices必须是Indices的实例。
- 泛型Where子句要求SequenceIndices的迭代器其所有的元素都是Int类型。这样就能确保在序列Sequence中的索引和容器(Container)里面的索引类型是一致的。
综合一下,这些约束意味着传入到indices下标是一个整数的序列.
(译者原来的Container协议subscript必须是Int型的扩展中新的subscript允许下标是一个的序列而非单一的值。)