我遇到了一个我无法解决的类型推断错误。我附上了下面最重要的片段。解析过程由Decoder
中的APIClient
单独完成。
为什么APIClient
的{{1}}无法识别execute
是T
,因为行[Chapter]
拥有该类型?
completion(Result.success(decodedData))
上面的代码段是我在func loadFeed(completion: @escaping (Result<[Chapter]>) -> Void) {
APIClient.shared.execute(APIRequest.loadFeed) { response in
guard let decodedData = response.decodedData else { return }
completion(Result.success(decodedData))
}
}
课程中调用APIClient
的方式。
Services
修改
为了澄清,下面的代码段是我class APIClient: APIClientProtocol {
static let shared = APIClient()
func execute<T: Decodable>(_ apiRequest: APIRequestDefining,
responseDecoder: ResponseDecoder = .jsonDecoding,
completionHandler: @escaping (Response<T>) -> Void) {
var response = Response<T>(request: request, httpResponse: dataResponse.response, data: dataResponse.data)
do {
try responseDecoder.decode(response: &response)
} catch {
response.error = error
}
completionHandler(response)
}
}
public struct Response<T> {
var decodedData: T?
}
enum Result<Value> {
case success(Value)
case failure(Error)
}
对推断出的对象的原始响应的位置和方式。
decode
修改!!!!:
我发现了一个非常奇怪的事情,我删除了struct JSONResponseDecoder: ResponseDecoding {
func decode<T: Decodable>(response: inout Response<T>) throws {
guard let data = response.data else { return }
do {
try response.decodedData = JSONDecoder().decode(T.self, from: data)
} catch {
throw(ApplicationError(errorType: .decodingError))
}
}
}
的行,它运行得很好,为什么呢?
答案 0 :(得分:2)
你说,&#34;执行不承认T是[Chapter]&#34;,我想知道你为什么这么认为。
您有一个loadFeed函数,其中一个完成块使用泛型类型的章节。
然后你有一个带泛型类型T的执行方法。当你调用你的execute方法时,它对类型章节一无所知。
我遇到与您相同的错误的示例:
func execute<T>(completionHandler: @escaping (T) -> Void) {
}
self.execute { (result) in
}
解决方案是转换参数以便可以推断出T.在你的情况下:
func execute<T>(completionHandler: @escaping (T) -> Void) {
}
self.execute { (result:[Chapter]) in
}
泛型是惊人的:)
答案 1 :(得分:0)
您的completionHandler
会使用泛型类型的参数,因此请在闭包中明确您的类型,否则无法推断出类型:
func loadFeed(completion: @escaping (Result<[Chapter]>) -> Void) {
APIClient.shared.execute(APIRequest.loadFeed) { (chapters: [Chapter]) -> () in
guard let decodedData = chapters.decodedData else { return }
completion(Result.success(decodedData))
}
}
答案 2 :(得分:-1)
我通过另一篇文章找到了答案。
错误的原因是编译器仅在闭包中有单个语句时引用闭包返回类型。
https://forums.swift.org/t/problems-with-closure-type-inference/11859/2