【问题标题】:Defining typeliases declared in other protocols定义在其他协议中声明的类型别名
【发布时间】:2016-02-27 18:24:01
【问题描述】:

我正在创建一个从 CollectionType 扩展的协议,但是,我正在引入新的类型别名,以消除 CollectionType 中对 Element 的需求(或者更确切地说,它们允许我计算它)。

我将使用一个简单的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) 的最佳方法是什么,以便我可以在协议扩展中使用它?这甚至可能吗?

【问题讨论】:

  • 你真正想做什么? MapType 是什么的集合,在什么意义上它是一个集合?
  • @matt 好像MapType 大致是一个基于这里的有序字典。
  • 请注意,在 Swift 2.2 中,“typealias”这个词的使用将被取消:它将被称为“associatedtype”。
  • MapType 只是一个简单的例子,但它确实是我需要定义的协议,因为我们没有抽象类(实际上我正在实现一组结构)。发布此消息后,我探索了独立于 CollectionType 定义 MapType 的可能性,但现在似乎没有完美的选择,所以像 nhgrif 这样的 where 子句建议可能是我目前最好的选择。

标签: swift inheritance protocols


【解决方案1】:

我们不一定强制CollectionType 协议继承的Element 类型一定是由KeyValue 类型从MapType 组成的元组.

但是,我们可以将协议扩展限制为仅将firstKey 方法添加到那些确实符合协议的方法,使用where 语句。

考虑这个简化的例子:

protocol Base {
    typealias Element

    func first() -> Element?
}

protocol Child: Base {
    typealias Key
    typealias Value

    func last() -> (Key, Value)?
}

extension Child where Self.Element == (Self.Key, Self.Value) {
    var firstKey:Key? { return self.first()?.0 }
}

struct ChildStruct: Child {
    func first() -> (String, Int)? {
        return ("Foo", 1)
    }

    func last() -> (String, Int)? {
        return ("Bar", 2)
    }
}

let c = ChildStruct()
let first = c.first()
let firstKey = c.firstKey

【讨论】:

    【解决方案2】:

    您基本上是在尝试在协议中创建 where 子句。这在今天的 Swift 中是不可能的。您不能基于其他关联类型来约束关联类型。也许有一天,但不是今天。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多