簡體   English   中英

返回泛型時的 Swift 協議一致性

[英]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一種類型,一種在運行時指定的同質具體類型。
成像Tclass 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM