扩展 CollectionType 时计算元素类型

Computing Element Type When Extending CollectionType

我正在尝试实现一个符合 to/extends CollectionType 的协议,但是它不采用显然是元素类型的单一泛型类型,所以我想能够 compute/force Generator.Element.

的类型

我将以地图协议为例:

protocol Map : CollectionType {
    typealias Key
    typealias Value

    subscript(key:Key) -> Value? { get }
}

有什么方法可以指定 Self.Generator.Element 必须是 (Key, Value),而不是输入作者的文档?

您想定义 CollectionType 的子协议,并在 CollectionType.Generator.Element 嵌套类型上附加约束。这个嵌套类型属于CollectionType.Generator嵌套类型,被约束为GeneratorType,所以首先我们需要引入一个GeneratorType的子协议,附加约束:

protocol KeyValueGeneratorType: GeneratorType {

    associatedtype Key
    associatedtype Value

    mutating func next() -> (Key, Value)?

}

然后我们可以引入一个带有附加约束的CollectionType的子协议:

protocol KeyValueCollectionType: CollectionType {

    associatedtype Generator: KeyValueGeneratorType

}

Dictionary 类型实际上符合我们的协议,所以我们只需要一个简短的声明来表明这一点:

extension DictionaryGenerator: KeyValueGeneratorType {}
extension Dictionary: KeyValueCollectionType {}

您必须创建要符合的生成器元素类型。例如。

protocol SpecialElement {
    typealias key : Int { get }
    typealias Value : Int { get }
}

然后:

extension CollectionType where Self.Generator.Element: SpecialElement {
      func addValues() -> Int {
         var total = 0
         for item in self {
           total += item.Value
         }
      return total       
     }
}