"收集的含义是什么?Indices.Iterator.Element == Index"

时间:2016-12-30 05:23:12

标签: swift

我无法弄清楚" 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
    }
}

2 个答案:

答案 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()

现在,ab中的哪一个拥有成员foo?答案是b

由于扩展程序的通用约束条件指出TU必须是同一类型,因此扩展程序仅应用于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。数组能够符合您的协议,因为IndexCountableRange<Int>)的迭代器元素和CountableRange<Int>.Iterator.Element类型的元素都是Index