簡體   English   中英

Swift generics - 無法將值轉換為類型

[英]Swift generics - cannot convert value to type

我對 swift 中的 generics 有疑問。

我正在構建簡單的 http 客戶端,我想擴展它以添加緩存。 我在這里使用這篇出色的帖子構建了緩存解決方案。

我希望能夠在初始化時將緩存實例傳遞給我的客戶端,因此它需要能夠保存符合Codable的不同數據類型。

這是我到目前為止所得到的(緩存實現如文章中所述):

數據:

struct CountryResult: Codable {
    let meta: Meta //confroms to Codable
    let results: [Country] //conforms to Codable
}

緩存:

final class Cache<Key: Hashable, Value> {
// cache implementation
}

// MARK: - Codable

extension Cache.Entry: Codable where Key: Codable, Value: Codable {}
extension Cache: Codable where Key: Codable, Value: Codable {
    convenience init(from decoder: Decoder) throws {
        self.init()

        let container = try decoder.singleValueContainer()
        let entries = try container.decode([Entry].self)
        entries.forEach(insert)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(keyTracker.keys.compactMap(entry))
    }
}

http 客戶端:

struct HttpService {

    let service: BaseUrl
    let cache: Cache<URL, Codable>

    init(service: String = "https://some.service/api", cache: Cache<URL, Codable> = Cache()) {
        self.service = service
        self.cache = cache
    }

    // performs http get
    func get<T: Codable>(endpoint: String, completion: @escaping (T?, Error?) -> Void) {
        guard let url = buildUrl(endpoint) else {
            print("Invalid url")
            return
        }

        if let cachedData = cache[url] as? T {
            print("Cache hit for: \(url)")
            completion(cachedData, nil)
            return
        } else {
            print("Cache miss for: \(url)")
        }

        //data not in cache, go to network
        //....
    }

現在,我希望能夠在請求不同數據類型的不同視圖控制器中實例化這個 http 客戶端。 我還想分別保存每個 VC 緩存,因此在初始化 VC 時,我試圖查找緩存是否存儲到磁盤並像這樣加載它:

let urls = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
let cacheUrl = urls[0].appendingPathComponent("/v1/test.cache")
if let data = try? Data(contentsOf: cacheUrl) {
    let cache  = try? JSONDecoder().decode(Cache<URL, CountryResult>.self, from: data) ?? Cache<URL, CountryResult>()
    let httpClient = HttpService(service: "https://some.service/api", cache: cache) //ERROR
}

但我收到以下錯誤,我不完全理解: Cannot convert value of type 'Cache<URL, CountryResult>?' to expected argument type 'Cache<URL, Codable>' (aka 'Cache<URL, Decodable & Encodable>') Cannot convert value of type 'Cache<URL, CountryResult>?' to expected argument type 'Cache<URL, Codable>' (aka 'Cache<URL, Decodable & Encodable>')

如果CountryResult confroms to Codable aka Decodable & Encodable為什么它不能被轉換

如果您更改以下代碼

let cache: Cache<URL, Codable>

作為

let cache: Cache<URL,T: Codable>

在 HttpService 結構中,希望它會起作用。

根據Swift doc ,在 Generics 中,允許具有符合 class 或協議或協議組成的類型參數,而不僅僅是協議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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