【发布时间】:2020-02-14 02:50:41
【问题描述】:
我已经建立了一个通用存储库,它返回我要求的资源。在我尝试通过将几个 fetch 调用包装到 DispatchGroup 来执行分组请求之前,这工作得很好。存储库是一个泛型类,指示返回类型。
我将每个单独获取的响应存储到字典中,一旦它们都准备好,我会将字典转换为预期的返回类型。
当泛型是 [Something] 类型(即 T == [Something])时,问题就来了
public typealias RepoCompletion<T: Codable> = (Result<T?, Error>) -> Void
public func fetch<T: Entity>(_ resources: [FetchResource<T>], completion: @escaping RepoCompletion<T>) {
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
let group = DispatchGroup()
let valueSyncQueue = DispatchQueue(label: "Repo.ValueSync")
var values = [String: T]()
for resource in resources {
group.enter()
self.localDataSource.fetch(resource) { result in
switch result {
case .success(let value):
if let value = value {
valueSyncQueue.sync {
values[resource.description] = value
}
}
case .failure(_): break
}
group.leave()
}
}
group.wait(timeout: .now() + 10)
let flattenedValues = resources.compactMap({ values[$0.description] }).flatMap({ $0 })
completion(.success(flattenedValues))
}
}
以上代码无法编译。错误显示Member 'success' in 'Result<_?, Error>' produces result of type 'Result<Success, Failure>', but context expects 'Result<_?, Error>'。我认为问题来了是因为泛型类型是 [] 并且编译器需要帮助。
调试时查看类型:
(lldb) po type(of: resources.compactMap({ values[$0.description] }))
Swift.Array<Swift.Array<Schedule>>
(lldb) po type(of: resources.compactMap({ values[$0.description] }).flatMap({ $0 }))
Swift.Array<Schedule>
(lldb) po type(of: flattenedValues)
Swift.Array<Swift.Array<Schedule>>
我不明白为什么表达式let flattenedValues = resources.compactMap({ values[$0.description] }).flatMap({ $0 }) 在评估后左侧和右侧的类型不同:S
假设 T == [时间表]。我希望values 是 [String: [Schedules]]。然后当.compactMap 我期望 [[Schedules]] 的结果,最后.flatMap 返回 [Schedules](即 T)。但是我错过了一些东西,或者我没有得到它。
如果我尝试帮助编译器并强制将 flattenedValues 转换为 as! T,返回时崩溃了
无法将“Swift.Array”(0x1058073b0)类型的值转换为“Schedule”(0x1044ac928)。 2019-10-17 09:48:14.585362+0200 Chicisimo[86448:2426001] 无法将“Swift.Array”(0x1058073b0)类型的值转换为“Schedule”(0x1044ac928)。
我不太明白,因为 T 是 [Schedule] 类型,而不是 Schedule 类型。
任何帮助将不胜感激!谢谢!
【问题讨论】:
-
可以给我们
RepoCompletion的声明吗? -
我已经编辑了添加它的问题。
标签: ios arrays swift generics higher-order-functions