符合带有关联值的类型的协议 [英] Protocol conforming to type with associated value

查看:61
本文介绍了符合带有关联值的类型的协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下片段:

protocol MyProtocol: Identifiable where ID == UUID {var id: UUID { 获取}}var 测试:[MyProtocol] = []

<块引用>

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

为什么这不起作用?where ID == UUID 不应该消除错误所涉及的歧义吗?我在这里遗漏了什么吗?

我认为这个问题类似于这个问题:在 swift 中使用协议作为数组类型和函数参数

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

谢谢!

编辑

因此,在试验 SwiftUI 和 struct 数据模型时出现了这个问题.我一直为任何类型的数据模型使用类,但似乎 SwiftUI 想让你尽可能多地使用结构(我仍然不明白这在现实中是如何可能的,但这就是为什么我正在试验中).

在这种特殊情况下,我尝试让管理器包含所有符合 MyProtocol 的结构.例如:

protocol MyProtocol: Identifiable where ID == UUID {var id: UUID { 获取}}struct A: MyProtocol {//第一个数据模型var id: UUID = UUID()}struct B: MyProtocol {//第二个数据模型var id: UUID = UUID()}类数据管理器:ObservableObject {var myData: [MyProtocol]}...

我实际上不必在 MyProtocol 上声明 Identifiable,但我认为它会更好更干净.

解决方案

因为这不是 Swift 的当前功能.一旦有关联类型,总会有关联类型.它不会因为你限制它而消失.而且一旦有了关联类型,就不是具体的了.

没有办法以这种方式继承"协议.你的意思是:

protocol MyProtocol {var id: UUID { 获取}}

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

struct X: MyProtocol, Identifiable {变量 ID:UUID}

(注意不需要 where 子句.)

今天没有 Swift 功能允许您说符合 X 的类型隐式符合 Y".今天也没有 Swift 功能允许符合 Identifiable with ID==UUID"的数组.(这称为广义存在主义,目前尚不可用.)

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

I've got the following snippet:

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


var test: [MyProtocol] = []

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

Why doesn't this work? Shouldn't the where ID == UUID remove the ambiguity the error is concerned with? Am I missing something here?

I think this question is similar to this one: Usage of protocols as array types and function parameters in swift

However, I would have assumed that adding where ID == UUID should fix the problem? Why is that not the case?

Thanks!

Edit

So, this problem has occurred while experimenting with SwiftUI and struct data models. I've always used classes for any kind of data model but it seems like SwiftUI wants to get you to use structs as often as possible (I still don't see how that's realistically possible but that's why I'm experimenting with it).

In this particular case, I tried to have a manager that contains structs that all conform to MyProtocol. For example:

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

...

I don't actually have to declare Identifiable on MyProtocol but I thought it would be nicer and cleaner.

解决方案

Because this is not a current feature of Swift. Once there is an associated type, there is always an associated type. It doesn't go away just because you constrain it. And once it has an associated type, it is not concrete.

There is no way to "inherit" protocols this way. What you mean is:

protocol MyProtocol {
    var id: UUID { get }
}

And then you can attach Identifiable to structs that require it:

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

(note that no where clause is required.)

There is no Swift feature today that allows you to say "types that conform to X implicitly conform to Y." There is also no Swift feature today that allows for an Array of "things that conform to Identifiable with ID==UUID." (That's called a generalized existential, and it's not currently available.)

Most likely you should go back to your calling code and explore why you require this. If you post the code that iterates over test and specifically requires the Identifiable conformance, then we may be able to help you find a design that doesn't require that.

这篇关于符合带有关联值的类型的协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆