[英]Swift protocol conformance when returning a generic
這是一個例子:
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 {}
為什么這樣做:
A)當T
是泛型而不是類型時嘗試轉換為T
? B) 不承認FeedItemModel
符合FeedItem
?
func items<T>() -> [T]? where T : FeedItem
這表示調用者可以將T
定義為他們想要的任何內容,只要T
符合 FeedItemModel,並且此 function 將返回這些的可選數組。
FeedItemModel 是符合 FeedItem 的東西,但不承諾是調用者請求的類型T
例如,考慮:
class OtherModel: FeedItem {}
根據您的 function 簽名,我可以這樣做:
let ms: [OtherModel]? = FeedModel().items()
但是您的 function 不會返回[OtherModel]?
大部頭書。 我懷疑您實際上並不是說這是通用的。 我希望你的意思是:
func items() -> [FeedItemModel]?
或者可能
func items() -> [FeedItem]?
(雖然在做后一個之前我會非常努力地思考,並確保協議存在確實在這里做了有用的工作。)
一個)
T
是一種類型,一種在運行時指定的同質具體類型。
成像T
是class Foo: FeedItem
很明顯FeedItemModel
不能轉換為Foo
二)
FeedItemModel
被識別為符合FeedItem
但這無關緊要。
它通常是 generics 和協議的混淆。 泛型類型不是協變的。 如果您需要協變類型,請使用關聯類型。
你可以忽略 generics 因為它只適用於那個 function 並且不需要它,因為直接說返回類型是[FeedItem]?
產生相同的結果
protocol Feed {
func items() -> [FeedItem]?
}
class FeedModel: Feed, Decodable {
func items() -> [FeedItem]? {
return [OtherModel]()
}
}
另一方面,如果您想要一個通用協議,那么您應該使用關聯類型
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.