Я создал общий репозиторий, который возвращает запрашиваемые ресурсы. Это работает нормально, пока я не попробую выполнить групповой запрос, поместив несколько вызовов извлечения в 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>>
Я не понимаю, почему выражение *У 1014 * есть разные типы для левой и правой сторон после оценки: S
Скажем, T == [Расписания]. Я ожидаю, что values
будет [Строка: [Расписания]]. Затем, когда .compactMap
, я ожидаю, что результат [[Расписания]] и, наконец, .flatMap
вернет [Расписания] (т.е. T). Но я что-то упускаю или не понимаю.
Если я попытаюсь помочь компилятору и принудительно привести приравненные значения к значению! T, он аварийно завершает работу, возвращая
Невозможно привести значение типа 'Swift.Array' (0x1058073b0) к 'Schedule' (0x1044ac928). 2019-10-17 09: 48: 14.585362 + 0200 Chicisimo [86448: 2426001] Не удалось преобразовать значение типа «Swift.Array» (0x1058073b0) в «Расписание» (0x1044ac928).
Что я не совсем понимаю, потому что T
относится к типу [Schedule]
, а не к типу Schedule
.
Любая помощь будет принята с благодарностью! Спасибо!