使用Swift在子协议中指定父协议的关联类型

时间:2015-08-24 15:30:11

标签: swift protocols associated-types

在Swift 2中,我有一个协议:

protocol Protocol {
    typealias Type
}

如果我想使用Protocol而不定义Type使用的类型:

var protocol1: Protocol

然后我收到以下错误:

  

协议'协议'只能用作通用约束,因为它具有自我或相关类型要求

很清楚为什么这不起作用。

我有另一个协议,它继承自第一个协议,并指定关联的类型Type应该是String

protocol AnotherProtocol: Protocol {
    typealias Type = String
}

当我尝试使用此协议时,会发生同样的错误:

var protocol2: AnotherProtocol
  

协议'AnotherProtocol'只能用作通用约束,因为它具有Self或相关类型要求

为什么我收到错误,虽然我已经指定了相关的类型?

第二个协议是否有另一种方法来指定父协议的关联类型,而不必在实现第二个协议的每个类中再次指定它?

1 个答案:

答案 0 :(得分:2)

您的错误不是来自协议的声明或定义,而是来自您尝试使用它们的方式。有两种基本方法可以使用协议:作为伪类型或作为约束。声明如下变量时:

var protocol1: Protocol

您使用的协议就像是一种类型:protocol1的类型是Protocol。这与将其用作约束不同。 其他类型符合协议,如果它被用作约束:

struct SomeStruct: Protocol {...

现在,您可以以任何一种方式使用协议,但这两种方式都有一些缺点。首先,您不能将“协议”的异构集合存储为约束,而您可以将协议用作类型。

其次,如果对自身或相关类型有要求,则不能再将该协议用作类型。

所以,这就是我认为你正在寻找的东西。你的第一个协议:

protocol Protocol {
  typealias Type
}

然后是第二个:

protocol InheritingProtocol {
  typealias Type = String
}

现在,如果您希望某些内容符合第二个协议,则必须将其用作约束。这意味着某些类型符合协议,然后您可以拥有该类型的实例

struct SomeType : InheritingProtocol {}

let someInstance = SomeType()