协议符合类型并具有关联值

时间:2020-04-15 18:56:36

标签: swift protocols

我有以下代码段:

protocol MyProtocol: Identifiable where ID == UUID {
    var id: UUID { get }
}


var test: [MyProtocol] = []

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

为什么这行不通? where ID == UUID是否应该消除错误所涉及的歧义?我在这里想念东西吗?

我认为这个问题类似于以下问题:Usage of protocols as array types and function parameters in swift

但是,我本来以为添加where ID == UUID应该可以解决此问题?为什么不是这样?

谢谢!

编辑

因此,在尝试SwiftUI和结构数据模型时发生了此问题。我一直在为任何类型的数据模型使用类,但似乎SwiftUI希望让您尽可能多地使用结构(我仍然看不到这在现实中是如何可能的,但这就是我正在尝试的原因)。

在这种情况下,我尝试使用一个包含全部符合MyProtocol的结构的管理器。例如:

protocol MyProtocol: Identifiable where ID == UUID {
    var id: UUID { get }
}

struct A: MyProtocol { // First data model
    var id: UUID = UUID()
}

struct B: MyProtocol { // Second data model
    var id: UUID = UUID()
}

class DataManager: ObservableObject {
    var myData: [MyProtocol]
}

...

我实际上不必在Identifiable上声明MyProtocol,但我认为这样会更好,更简洁。

1 个答案:

答案 0 :(得分:4)

因为这不是Swift的当前功能。一旦存在关联的类型,总会有关联的类型。它不会仅仅因为您约束它而消失。并且一旦它具有关联的类型,就不是具体的。

无法以这种方式“继承”协议。你的意思是:

protocol MyProtocol {
    var id: UUID { get }
}

然后您可以将Identifiable附加到需要它的结构上:

struct X: MyProtocol, Identifiable {
    var id: UUID
}

(请注意,不需要where子句。)

今天没有Swift功能可以让您说“符合X的类型隐式符合Y。”如今,还没有Swift功能允许使用“符合ID == UUID可识别的事物”数组。 (这被称为广义存在性,目前尚不可用。)

最有可能您应该回到调用代码并探究为什么需要此代码。如果您发布的代码在test上进行迭代,并且特别需要Identifiable一致性,那么我们也许可以帮助您找到不需要的代码。