[英]Swift protocol conformance when returning a generic
Here's an example:这是一个例子:
protocol Feed {
func items<T>() -> [T]? where T: FeedItem
}
protocol FeedItem {}
class FeedModel: Feed, Decodable {
func items<T>() -> [T]? where T : FeedItem {
return [FeedItemModel]() // Error: Cannot convert return expression of type '[FeedItemModel]' to return type '[T]?'
}
}
class FeedItemModel: FeedItem, Decodable {}
Why does it:为什么这样做:
A) try to convert to T
when T
is a generic, not a type? A)当
T
是泛型而不是类型时尝试转换为T
? B) does not recognize FeedItemModel
as conforming to FeedItem
? B) 不承认
FeedItemModel
符合FeedItem
?
func items<T>() -> [T]? where T : FeedItem
This says that the caller can define T
to be whatever they want, as long as T
conforms to FeedItemModel, and this function will return an optional array of those.这表示调用者可以将
T
定义为他们想要的任何内容,只要T
符合 FeedItemModel,并且此 function 将返回这些的可选数组。
FeedItemModel is something that conforms to FeedItem, but it is not promised to be the type T
that the caller requested. FeedItemModel 是符合 FeedItem 的东西,但不承诺是调用者请求的类型
T
As an example, consider:例如,考虑:
class OtherModel: FeedItem {}
According to your function signature, I can do this:根据您的 function 签名,我可以这样做:
let ms: [OtherModel]? = FeedModel().items()
But your function won't then return [OtherModel]?
但是您的 function 不会返回
[OtherModel]?
to me.大部头书。 I suspect you don't actually mean this to be generic.
我怀疑您实际上并不是说这是通用的。 I expect you mean:
我希望你的意思是:
func items() -> [FeedItemModel]?
or possibly或者可能
func items() -> [FeedItem]?
(Though I would think very hard before doing the latter one and make sure that the protocol existential is really doing useful work here.) (虽然在做后一个之前我会非常努力地思考,并确保协议存在确实在这里做了有用的工作。)
A)一个)
T
is a type, a homogenous concrete type specified at runtime. T
是一种类型,一种在运行时指定的同质具体类型。
Imaging T
is class Foo: FeedItem
it's obvious that FeedItemModel
cannot be converted to Foo
成像
T
是class Foo: FeedItem
很明显FeedItemModel
不能转换为Foo
B)二)
FeedItemModel
is recognized as conforming to FeedItem
but this is irrelevant. FeedItemModel
被识别为符合FeedItem
但这无关紧要。
It's often a mix-up of generics and protocols.它通常是 generics 和协议的混淆。 Generic types are not covariant.
泛型类型不是协变的。 If you need covariant types use an associated type.
如果您需要协变类型,请使用关联类型。
Either you can ignore generics because because it only applies to that one function and it isn't needed since directly saying that the return type is [FeedItem]?
你可以忽略 generics 因为它只适用于那个 function 并且不需要它,因为直接说返回类型是
[FeedItem]?
yields the same result产生相同的结果
protocol Feed {
func items() -> [FeedItem]?
}
class FeedModel: Feed, Decodable {
func items() -> [FeedItem]? {
return [OtherModel]()
}
}
If you on the other hand want a generic protocol then you should use a associated type另一方面,如果您想要一个通用协议,那么您应该使用关联类型
protocol Feed2 {
associatedtype T: FeedItem
func items() -> [T]?
}
class FeedModel2: Feed2, Decodable {
typealias T = FeedItemModel
func items() -> [T]? {
return [FeedItemModel]()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.