Swift Generics函数具有转义关闭功能

时间:2018-05-29 04:58:09

标签: ios swift generics closures

我有方法:

func getUsers(completion: @escaping (_ users: [User]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in
 var users = [User]()
 users = try JSONDecoder().decode(Array<User>.self, from: responseData)
}

但我想把这个功能做得更通用。 我试过

    func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in 
      var users = [T]()
      users = try JSONDecoder().decode(Array<T>.self, from: responseData)
      completion(users, nil)
}

但是当我从转义关闭调用此func用户数组时是[_]。如果我只使用T用户数组是[User.Type]并且它不符合Decodable,那么我可以JSONDecoder().decode。怎么看?

2 个答案:

答案 0 :(得分:1)

  

阵列&LT;用户&gt;不能转换为&#39; [_]?&#39;

这是因为 _ users:[T]?类型 可选

您的方法工作正常,您只需要定义可选数组。

 self.getUsers{ (res:Array<User>?, error) in

 }

我创建了一个类似的

 func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) {

        URLSession.shared.dataTask(with: URL(string: "test")!) { (data, res, error) in
            guard let resData = data else  {completion(nil,"data is nil"); return}
            do {
                var users = [T]()
                users = try JSONDecoder().decode(Array<T>.self, from:resData)
                completion(users, nil)

            } catch {
                completion(nil, error.localizedDescription)
            }
        }

并称之为

     self.getUsers{ (res:Array<User>?, error) in

    }

这是struct

struct User :Codable {
    var name:String?
}

答案 1 :(得分:0)

嘿Hds你已经正确地完成了大部分工作,只有一个缺失点是关于Decodables如何工作的知识。

Decodable数组也是可解码的。所以我想说的是你不需要明确提到要解码Array<T>.self,只要你传递给你自己的函数你就可以把它自己期待Array<T>.self所以T =&gt; Array<T>

因此,在您调用此函数并将[User]作为通用参数传递时,T在解码时将为Array<User>.self。所以代码应该是这样的。我不确定代码是否会100%编译,因为我有一些缺少的组件,但它可以解决这个问题。

func get<T:Deocdable>(completion: @escaping (_ object: T?,_ error: String?) -> ()) {
    router.request(.getUsers) { (data, response, error) in
        do {
            let object = try JSONDecoder().decode(T.self, from: responseData)
        } catch {
            fatalError("Decoding failed because: ", error.localizedDescription)
        }
}

我还添加了do catch块,因为try JSONDecoder()会抛出。

另外要添加如何调用方法,如下所示:

get { (users: [User]?, error) in

}

希望这会有所帮助。