如何在Swift 4中引用通用的Decodable结构

时间:2017-10-26 19:07:42

标签: struct swift4 decodable

我有一个我想重用的函数,并让它接受Decocable结构的参数。例如,这是我当前代码的简化(假设“MyDecodableStruct”是在应用程序的其他地方声明的可解码结构):

 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
    }
}

而不是说“MyDecodableStruct”,我希望它是我作为参数传递的任何Decodable结构。像这样:

 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
    }
}

我会称之为

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

我无法弄清楚如何让它工作的语法。我得到的错误是

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

有关处理此问题的最佳方法的任何想法吗?

1 个答案:

答案 0 :(得分:11)

如果要将类型作为参数传递,则需要将参数的类型声明为元类型。在您的情况下,它是一个通用类型,需要符合Decodable

所以你可能需要写这样的东西:

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说类型不能嵌套在通用上下文中,所以我把它移到外部非泛型上下文中。

将其命名为:

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