尝试编写一个通用函数,用于将JSON解析为可编码的Structs

Sta*_*yer 0 generics swift codable

我正在解析像这样的JSON

struct ExampleStruct : Codable {
     init() {

     }
     // implementation
}

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let decoder = JSONDecoder()
        let object =  try decoder.decode(ExampleStruct.self, from: jsonData)
    } catch {
        print("Coding error - \(error)")
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好,但是我一直试图在周末学习泛型.我正在尝试编写一个方法,我传入一个Codable结构类型和一个JSON字符串,它返回我想要的类型的对象.

我尝试过以下方法: -

func getType<T>(_ anyType: T.Type, from jsonString:String) -> T? {

if let jsonData = jsonString.data(using: .utf8) {
    do {
        let decoder = JSONDecoder()
        let object =  try decoder.decode(anyType, from: jsonData)//Errors here
        return object as? T
        return nil
    } catch {
        print("Coding error - \(error)")
       return nil
    }
  }
return nil
}
Run Code Online (Sandbox Code Playgroud)

然后当我想做上述事情

 if let exampleStruct:ExampleStruct = getType(type(of: ExampleStruct()), from: jsonString) {
  print(exampleStruct)
 }
Run Code Online (Sandbox Code Playgroud)

但是在let = object行上我得到以下错误

无法将类型'T'的值(全局函数'getType(:from :)'的泛型参数)转换为期望的参数类型'T'(实例方法的通用参数'decode(:from :)')

在参数类型'T.Type'中,'T'不符合预期类型'Decodable'

正如我所说的那样,我本周末一直试图了解仿制药,但我的理解中显然已经达到了一个障碍.有没有解决这个问题,确实是我正在尝试做甚至可能或一个好主意?

vad*_*ian 5

首先,强烈建议throw将调用函数的错误移交给调用者.
其次,Data从UTF8字符串创建的文件永远不会失败.

您必须将泛型类型约束为Decodable,不需要将类型作为额外参数传递.

您的功能可以减少到

func getType<T : Decodable>(from jsonString:String) throws -> T {
    let jsonData = Data(jsonString.utf8)
    return try JSONDecoder().decode(T.self, from: jsonData)
}
Run Code Online (Sandbox Code Playgroud)