首页 > 解决方案 > 回调中的类型推断错误

问题描述

我遇到了无法解决的类型推断错误。我附上了下面最重要的片段。解析过程DecoderAPIClient.

为什么APIClient'sexecute不能识别Tis the [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))
    }
}

上面的片段是我APIClientServices课堂上的称呼。

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))
        }
    }
}

编辑!!!!:

我发现了一件很奇怪的事情,我删除了带有 的行guard,一切正常,这是为什么呢?

之前之后在此处输入图像描述 在此处输入图像描述

标签: iosswiftnetworkingcallbacktype-inference

解决方案


您说,“执行不承认 T 是 [Chapter]”,我想知道您为什么会这样期望。

你有一个 loadFeed 函数,它有一个使用泛型 Chapter 的完成块。

然后你有一个泛型类型 T 的 execute 方法。当你调用你的 execute 方法时,它对 Chapter 类型一无所知。

我遇到与您相同的错误的示例:

 func execute<T>(completionHandler: @escaping (T) -> Void) {

 }
 self.execute { (result) in
 }

解决方案是转换参数以便可以推断出 T。在你的情况下:

func execute<T>(completionHandler: @escaping (T) -> Void) {

 }
 self.execute { (result:[Chapter]) in
 }

泛型是惊人的:)


推荐阅读