【发布时间】:2018-05-31 13:02:32
【问题描述】:
我遇到了标题所描述的问题:guard 语句由于某种原因中断了类型推断。我创建了一个Playground 项目来玩。
以下是一些用于设置的样板代码:
import Foundation
struct Model: Decodable {
var i: String
}
let jsonString = """
{
"i": "yes"
}
"""
let jsonData = jsonString.data(using: .utf8)
let theModel = try JSONDecoder().decode(Model.self, from: jsonData!)
struct Response<T> {
var decodedData: T?
}
enum Result<Value> {
case success(Value)
case failure
}
struct Client {
static let shared = Client()
private init() {}
func execute<T: Decodable>(completion: (Response<T>) -> ()) {
let decodedData = try! JSONDecoder().decode(T.self, from: jsonData!)
completion(Response(decodedData: decodedData))
}
}
问题来了:
struct ServicesA {
func loadSomething(completion: (Result<Model>) -> ()) {
Client.shared.execute { result in // error: generic parameter 'T' could not be inferred
guard let decodedData = result.decodedData else { return }
completion(Result.success(decodedData))
}
}
}
struct ServicesB {
func loadSomething(completion: (Result<Model>) -> ()) {
Client.shared.execute { result in
completion(Result.success(result.decodedData!))
}
}
}
ServicesA 中断,而ServicesB 编译。
如您所见,唯一的区别是guard let decodedData = result.decodedData else { return }。它破坏了类型推断,因此Client.shared.execute 函数抱怨T 无法推断。
我想知道为什么会发生这种情况以及处理此问题的最合适方法是什么。
【问题讨论】:
-
guard let decodedData = data else { return }应该是guard let decodedData = result.decodedData else { return } -
是的,这就是我刚刚输入的内容 :)
-
比较stackoverflow.com/q/42213656/2976878——闭包仅在包含单个语句时才参与类型推断。
-
@PrashantTukadiya 是的,谢谢,当我编辑到 stackoverflow 时,这是一个错字。但我的程序格式正确。刚刚编辑了我的问题。
-
@TonyLin 检查我的答案,它会帮助你
标签: ios swift type-inference swift-playground