我无法弄清楚" Indices.Iterator.Element == Index"的目的/意义。在以下代码中
extension Collection where Indices.Iterator.Element == Index {
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Generator.Element? {
return indices.contains(index) ? self[index] : nil
}
}
答案 0 :(得分:8)
通用约束语法where T == U
表示类型T
必须与类型U
的类型相同。
让我们先做一个更简单的例子:
protocol GenericProtocol {
associatedtype T
associatedtype U
}
extension GenericProtocol where T == U {
func foo() {}
}
class ConcreteClassA: GenericProtocol {
typealias T = Int
typealias U = Float
}
class ConcreteClassB: GenericProtocol {
typealias T = Int
typealias U = Int
}
let a = ConcreteClassA()
let b = ConcreteClassB()
现在,a
或b
中的哪一个拥有成员foo
?答案是b
。
由于扩展程序的通用约束条件指出T
和U
必须是同一类型,因此扩展程序仅应用于ConcreteClassB
,因为其T
和{{1} }都是U
。
立即返回您的代码。
在您的代码中,您说Int
必须与Indices.Iterator.Element
的类型相同。让我们分别说明这两种类型。
Index
是属性Indices
的类型。所以indices
是集合的每个索引的类型。另一方面,Indices.Iterator.Element
是可以放入集合下标的值的类型。这种约束似乎过多,但实际上并非如此。我想不出约束不正确的类型的例子。但是你可以从理论上创造出这样一种类型。这就是约束的原因。
如果没有约束,则无法编译:
Index
答案 1 :(得分:2)
HttpwebResponse
属性(类型为contains(_:)
)上调用 indices
,其参数名为Indices
(类型为index
)。唯一可行的方法是Index
元素与Indices
的类型相同。
添加此约束以断言这是真的,从而允许代码编译。
以Index
为例。其Array
关联类型设置为CountableRange<Int>
,其Indices
关联类型设置为Int
。数组能够符合您的协议,因为Index
(CountableRange<Int>
)的迭代器元素和CountableRange<Int>.Iterator.Element
类型的元素都是Index