定义在其他协议中声明的类型

时间:2016-02-27 18:24:02

标签: swift inheritance protocols

我正在创建一个从CollectionType扩展的协议,但是,我正在引入新的typealiases,以消除ElementCollectionType的需要(或者说,它允许我计算它)。

我将使用简单的MapType协议作为示例:

protocol MapType : CollectionType, DictionaryLiteralConvertible {
    typealias Key
    typealias Value

    func updateValue(theNewValue:Value, forKey theKey:Key) -> Value?
}

在上面的示例中,我真正需要做的是将Element重新定义为元组(Key, Value),但我不确定如何在协议中执行此操作而不是结构或阶级。

简单地添加typealias Element = (Key, Value)不会产生任何错误,但似乎也没有在协议的上下文中实际执行任何操作,例如,以下操作无效:

extension MapType {
    var firstKey:Key? { return self.generate().next()?.0 }
}

这会产生错误,因为生成器不会被识别为返回元组(即没有成员.0)。

在这种情况下,将Element定义为(Key, Value)的最佳方法是什么,以便我可以在协议扩展中使用它?这甚至可能吗?

2 个答案:

答案 0 :(得分:1)

我们不一定强制Element协议继承的CollectionType类型必然是由Key和{{1}组成的元组来自Value

的类型

但是,我们可以将协议扩展限制为仅使用MapType语句以这种方式将firstKey方法添加到符合协议的方法。

考虑这个简化的例子:

where

答案 1 :(得分:0)

您基本上是在协议中创建firstName = name.substring(0, name.indexOf(' ')); middleName = name.substring(name.indexOf(' ') + 1, name.lastIndexOf(' ')); lastName = name.substring(name.lastIndexOf(' ') + 1); 子句。今天在Swift中这是不可能的。您不能基于其他关联类型约束关联类型。可能有一天,但不是今天。

您需要重新考虑如何解决问题。可能的解决方案是使用通用结构而不是协议(否则您最终会在代码中出现大量重复的where子句。您可以查看最近的dotSwift talk以获取更详细的示例。