无法使用类型为 '(Codable.Type?
Cannot invoke 'decode' with an argument list of type '(Codable.Type?
我正在重构(尝试)一些前同事编写的网络代码,我想使用新的JSONDecoder
。
他的网络代码被包装成一个函数getData
:
func getData(modelToReturn:Proto.Type, configuredRequest:URLRequest) {
正如你从签名中看到的那样,在这个方法中你可以将模型指定为return(即哪个模型应该反序列化检索到的JSON:我不能说更好,我希望你能理解 :-)).
在这种情况下,Proto
是任何模型所遵循的协议。
例如
struct GroceryModel:Proto{
//...
}
然后以这种方式调用该方法:
net.getData(modelToReturn: GroceryModel.self, configuredRequest: grocery)
调用后,GroceryModel.self
被分配给 net
class (memberToReturn:Proto.Type?
) 的成员,然后 JSON 测试是否符合带有可失败初始化器的模型结构:
if let instance = modelToReturn?.init(json:jsonResult){...
我用以下协议做了一个小测试:
struct Test: Codable {
let name: String
let testers: [String]
}
我用这一行替换了大部分原始代码:
let test = try? JSONDecoder().decode(modelToReturn, from: jsonData)
我的想法是将 Codable.self
作为 getData
函数的第一个参数传递,但在最后一行出现错误:
Cannot invoke 'decode' with an argument list of type '(Codable.Type?, from: Data)'
那么,我怎样才能正确传递我的模型,以便它可以在 decode
函数中使用?
我必须说,我通过简单地将 modelToReturn
替换为 Test.self
手动测试了该行,错误消失了。
您可以像下面这样使用泛型。
protocol Proto {
}
struct Test: Codable, Proto {
let name: String
let testers: [String]
}
func getData<T>(type: T.Type, configuredRequest:URLRequest?) where T : Decodable {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(type, from: data)
debugPrint(test)
}
getData(type: Test.self, configuredRequest: nil)
已编辑。
如评论所述,您希望 Type 成为 class 的成员,该 class 具有 getData
。
在这种情况下,您可以将泛型应用于 class 定义,如下所示。
class DataFetcher<T> where T: Decodable {
func getData(configuredRequest:URLRequest?) {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(T.self, from: data)
debugPrint(test)
}
}
DataFetcher<Test>().getData(configuredRequest: nil)
我正在重构(尝试)一些前同事编写的网络代码,我想使用新的JSONDecoder
。
他的网络代码被包装成一个函数getData
:
func getData(modelToReturn:Proto.Type, configuredRequest:URLRequest) {
正如你从签名中看到的那样,在这个方法中你可以将模型指定为return(即哪个模型应该反序列化检索到的JSON:我不能说更好,我希望你能理解 :-)).
在这种情况下,Proto
是任何模型所遵循的协议。
例如
struct GroceryModel:Proto{
//...
}
然后以这种方式调用该方法:
net.getData(modelToReturn: GroceryModel.self, configuredRequest: grocery)
调用后,GroceryModel.self
被分配给 net
class (memberToReturn:Proto.Type?
) 的成员,然后 JSON 测试是否符合带有可失败初始化器的模型结构:
if let instance = modelToReturn?.init(json:jsonResult){...
我用以下协议做了一个小测试:
struct Test: Codable {
let name: String
let testers: [String]
}
我用这一行替换了大部分原始代码:
let test = try? JSONDecoder().decode(modelToReturn, from: jsonData)
我的想法是将 Codable.self
作为 getData
函数的第一个参数传递,但在最后一行出现错误:
Cannot invoke 'decode' with an argument list of type '(Codable.Type?, from: Data)'
那么,我怎样才能正确传递我的模型,以便它可以在 decode
函数中使用?
我必须说,我通过简单地将 modelToReturn
替换为 Test.self
手动测试了该行,错误消失了。
您可以像下面这样使用泛型。
protocol Proto {
}
struct Test: Codable, Proto {
let name: String
let testers: [String]
}
func getData<T>(type: T.Type, configuredRequest:URLRequest?) where T : Decodable {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(type, from: data)
debugPrint(test)
}
getData(type: Test.self, configuredRequest: nil)
已编辑。
如评论所述,您希望 Type 成为 class 的成员,该 class 具有 getData
。
在这种情况下,您可以将泛型应用于 class 定义,如下所示。
class DataFetcher<T> where T: Decodable {
func getData(configuredRequest:URLRequest?) {
let data = """
{
"name": "a test",
"testers": ["mike", "bob"],
}
""".data(using: .utf8)!
let test = try? JSONDecoder().decode(T.self, from: data)
debugPrint(test)
}
}
DataFetcher<Test>().getData(configuredRequest: nil)