回调中的类型推断错误

时间:2018-05-31 05:57:48

标签: ios swift networking callback type-inference

我遇到了一个我无法解决的类型推断错误。我附上了下面最重要的片段。解析过程由Decoder中的APIClient单独完成。

为什么APIClient的{​​{1}}无法识别executeT,因为行[Chapter]拥有该类型?

enter image description here

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)) } } } 的行,它运行得很好,为什么呢?

之前enter image description hereenter image description here

3 个答案:

答案 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