How to reference a generic Decodable struct in Swift 4

旧巷老猫 提交于 2019-12-09 04:46:29

问题


I have a function that I would like to reuse and have it accept a parameter of a Decocable struct. For example, this is a simplification of my current code (assume "MyDecodableStruct" is a Decodable struct declared elsewhere in the app):

 static func getResults(url: String, parameters: Parameters) {
    // On success REST response
     if response.result.isSuccess {
        struct Results: Decodable {
          let items: [MyDecodableStruct]
         }

      if let jsonResults = try? JSONDecoder().decode(Results.self, from: response.data!) {
        //success
    }
}

and instead of saying "MyDecodableStruct", I would like it to be any Decodable struct I pass in as a parameter. Something like this:

 static func getResults(url: String, parameters: Parameters, myStruct: Decodable) {
    // On success REST response
     if response.result.isSuccess {
        struct Results: Decodable {
          let items: [myStruct]
         }

      if let jsonResults = try? JSONDecoder().decode(Results.self, from: response.data!) {
        //success
    }
}

and I would call it like

 getResults(url: "url", parameters: nil, myStruct: MyDecodableStruct)

I cannot figure out the syntax on how to get this to work though. The errors I get are

Type 'Results' does not conform to protocol 'Decodable'
Expected element type

Any ideas on the best way to handle this?


回答1:


When you want to pass a type as a parameter, you need to declare the type of the parameter as metatype. In your case, it's a generic type which needs to conform to Decodable.

So you may need to write something like this:

struct Results<Element: Decodable>: Decodable {
    let items: [Element]
}
static func getResults<Element: Decodable>(url: String, parameters: Parameters?, myStruct: Element.Type) {
    //...
        // On success REST response
        if response.result.isSuccess {

            do {
                let jsonResults = try JSONDecoder().decode(Results<Element>.self, from: response.data!)
                //success
                print(jsonResults)
            } catch {
                //Better not dispose errors silently
                print(error)
            }
        }
    //...
}

Swift says types cannot be nested in generic context, so I moved it out to the outer non-generic context.

Call it as:

getResults(url: "url", parameters: nil, myStruct: MyDecodableStruct.self)


来源:https://stackoverflow.com/questions/46962021/how-to-reference-a-generic-decodable-struct-in-swift-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!