首页 > 解决方案 > 符合具有关联值的类型的协议

问题描述

我有以下片段:

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]
}

...

我实际上不必声明IdentifiableMyProtocol但我认为它会更好更干净。

标签: swiftprotocols

解决方案


因为这不是 Swift 的当前特性。一旦存在关联类型,就始终存在关联类型。它不会因为你限制它而消失。一旦它有一个关联的类型,它就不是具体的了。

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

protocol MyProtocol {
    var id: UUID { get }
}

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

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

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

今天没有 Swift 特性允许你说“符合 X 的类型隐式地符合 Y”。今天也没有 Swift 功能允许“符合 ID==UUID 的可识别事物”的数组。(这称为广义存在,目前不可用。)

很可能你应该回到你的调用代码并探索你为什么需要这个。如果您发布了迭代的代码test并且特别需要Identifiable一致性,那么我们可以帮助您找到不需要的设计。


推荐阅读