3

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

protocol Protocol {
    typealias Type
}

当我想使用Protocol而不定义要使用的类型时Type

var protocol1: Protocol

然后我收到以下错误:

协议“协议”只能用作通用约束,因为它具有 Self 或关联的类型要求

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


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

protocol AnotherProtocol: Protocol {
    typealias Type = String
}

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

var protocol2: AnotherProtocol

Protocol 'AnotherProtocol' 只能用作通用约束,因为它具有 Self 或关联的类型要求

尽管我已经指定了关联的类型,但为什么会出现错误?

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

4

1 回答 1

2

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

var protocol1: Protocol

您正在使用协议,就像它是一种类型:类型protocol1Protocol。这与将其用作约束不同。如果将其用作约束,则其他类型符合协议:

struct SomeStruct: Protocol {...

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

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

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

protocol Protocol {
  typealias Type
}

然后是第二个:

protocol InheritingProtocol {
  typealias Type = String
}

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

struct SomeType : InheritingProtocol {}

let someInstance = SomeType()
于 2015-08-24T19:46:31.090 回答