ios - Swift 泛型 - 无法将值转换为类型
问题描述
我对 swift 中的泛型有疑问。
我正在构建简单的 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>')
CountryResult
如果confroms 到Codable
aka为什么不能转换Decodable & Encodable
解决方案
如果您更改以下代码
let cache: Cache<URL, Codable>
作为
let cache: Cache<URL,T: Codable>
在 HttpService 结构中,希望它会起作用。
根据Swift doc,在泛型中,允许具有符合类或协议或协议组合的类型参数,而不仅仅是协议。
推荐阅读
- c++ - 我将如何清理这些 If 语句?
- port - 使用不同于 25 的端口时出现 Postfix 错误
- objective-c - 如何创建键入自定义图像的自定义键盘?
- python - 按 id 保持第一次出现的行,并在列中的值发生变化时保持第一次出现
- c++ - 我想禁用 CFiledialog 中的取消按钮
- java - 如何处理json配置中的条件管理器
- json - 如何在 Python 中使用 C3.ai Data Lake 正确获取所有基因组冠状病毒序列及其元数据?
- csv - 将 Google 表格的每个选项卡以 .csv 格式下载到硬盘
- c++ - 使用 at() 访问 std::map 元素是否比 operator[] 慢?
- javascript - 如何将 foreach 变量从 laravel 刀片传递到 javascript?