回调中的类型推断错误
type inference error in the callback
我遇到了无法解决的类型推断错误。我在下面附上了最重要的片段。解析过程由APIClient
.
中的一个Decoder
单独完成
为什么 APIClient
的 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))
}
}
上面的代码片段是我在 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
我遇到了无法解决的类型推断错误。我在下面附上了最重要的片段。解析过程由APIClient
.
Decoder
单独完成
为什么 APIClient
的 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))
}
}
上面的代码片段是我在 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