回调中的类型推断错误

type inference error in the callback

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

中的一个Decoder单独完成

为什么 APIClientexecute 无法识别 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))
    }
}

上面的代码片段是我在 Services class 中调用 APIClient 的方式。

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那一行,一切正常,这是为什么呢?

之前 之后

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

你说,"execute does not recognise the T is the [Chapter]",我想知道你为什么这么期望。

您有一个 loadFeed 函数,其完成块使用通用类型 Chapter。

那么你有一个带有泛型类型 T 的执行方法。当你调用你的执行方法时,它对类型 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
 }

泛型很棒 :)

我通过另一个post找到了答案。

错误的原因是当闭包中只有一条语句时,编译器只引用闭包 return 类型。

https://forums.swift.org/t/problems-with-closure-type-inference/11859/2