swift - 使用 Swift 在子协议(protocol)中指定关联的父协议(protocol)类型

标签 swift protocols associated-types

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

protocol Protocol {
    typealias Type
}

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

var protocol1: Protocol

然后我收到以下错误:

Protocol 'Protocol' can only be used as a generic constraint because it has Self or associated type requirements

很明显为什么这行不通。


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

protocol AnotherProtocol: Protocol {
    typealias Type = String
}

同样的错误发生,当我尝试使用这个协议(protocol)时:

var protocol2: AnotherProtocol

Protocol 'AnotherProtocol' can only be used as a generic constraint because it has Self or associated type requirements

尽管我已经指定了关联类型,但为什么我会收到错误消息?

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

最佳答案

您的错误不是来自协议(protocol)的声明或定义,而是来自您尝试使用它们的方式。您可以通过两种基本方式使用协议(protocol):作为伪类型或作为约束。当你像这样声明一个变量时:

var protocol1: Protocol

您正在像使用类型一样使用协议(protocol):protocol1 的类型是 Protocol。这与将其用作约束不同。 其他类型如果用作约束则符合协议(protocol):

struct SomeStruct: Protocol {...

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

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

那么,这就是我认为您正在寻找的东西。你的第一个协议(protocol):

protocol Protocol {
  typealias Type
}

然后是第二个:

protocol InheritingProtocol {
  typealias Type = String
}

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

struct SomeType : InheritingProtocol {}

let someInstance = SomeType()

关于swift - 使用 Swift 在子协议(protocol)中指定关联的父协议(protocol)类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32186127/

相关文章:

Swift - 如何获取从协议(protocol)扩展的类?

iOS Swift - 协议(protocol)发送委托(delegate)给错误的 TableViewController

swift - 协议(protocol)所有实现的返回类型

Swift - 协议(protocol)只能用作通用约束,因为它具有 Self 或关联的类型要求

haskell - Haskell 中的变量关联类型/数据类型

ios - 如何在 ibeacon 中使用唯一标识符?

ios - 在另一个类中时,Swift Firebase 身份验证不起作用

ios - 在过渡期间使 UINavigationBar 透明动画

ios - 如何向 Collection View 添加标签

swift - Swift 协议(protocol)类型别名中的默认类型可能吗?