[英]Need to satisfy Swift protocol requirement by using a specific subclass of the requirement (or type that conforms to it)
I have a protocol that I've created (in Swift 4.2), and one of its requirements is a property that is of the same type as the protocol itself. 我有一个我创建的协议(在Swift 4.2中),它的一个要求是一个与协议本身类型相同的属性。
As an example, I have a protocol defined like so: 举个例子,我有一个像这样定义的协议:
protocol A {
var a: A? { get set }
}
I have several Models that conform to this protocol: 我有几个符合此协议的模型:
class Model1: A {
var a: A?
}
class Model2: A {
var a: A?
}
For one of my models, I need to satisfy the protocol requirement by being more specific for the property defined by variable a
(ie the variable with the protocol type). 对于我的一个模型,我需要通过更具体地定义变量a
定义的属性(即具有协议类型的变量)来满足协议要求。 So for example I may want to implement Model2
as: 例如,我可能希望将Model2
实现为:
class Model2: A {
var a: Model1?
}
In this case since Model1
conforms to the protocol A
you would expect this to be able to satisfy the protocol requirement, however I get an error instead: 在这种情况下,由于Model1
符合协议A
您可以期望它能够满足协议要求,但是我得到了一个错误:
Type 'Model2' does not conform to protocol 'A' 类型'Model2'不符合协议'A'
Why is this happening, and what can I do to make it work as described above? 为什么会发生这种情况,我该怎么做才能让它如上所述工作?
Appendix 附录
I've modelled the above scenario in an Xcode Playground and here is a screenshot of the error I'm seeing. 我在Xcode Playground中对上面的场景进行了建模,这里是我看到的错误的屏幕截图。
To conform to protocol A, Model2
would need a member var a
that allows storing a reference to anything conforming to protocol A, not just a reference to a Model1
. 为了符合协议A, Model2
需要一个成员var a
,它允许存储对符合协议A的任何内容的引用,而不仅仅是对Model1
的引用。 So you can't do this. 所以你不能这样做。
You could do this with associated types: 您可以使用相关类型执行此操作:
protocol A {
associatedtype B: A
var a: B? { get }
}
This would let you declare Model2 with the specificity you wish: 这将允许您使用您希望的特异性声明Model2:
class Model2: A {
var a: Model1?
}
But unfortunately, that would mean you could no longer declare variables of type A
. 但遗憾的是,这意味着您无法再声明类型A
变量。 To fix that, you could use generic models: 要解决这个问题,您可以使用通用模型:
class Model1<T: A>: A {
var a: T?
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.