简体   繁体   English

带有转义转义的Swift泛型函数

[英]Swift Generics function with escaping closure

I have method: 我有方法:

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

But i want to do this function more generic. 但我想更通用地执行此功能。 I tried : 我试过了

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

But when i call this func users array from escaping closure is [_]. 但是,当我从逃逸闭包中调用此函数用户数组时,是[_]。 If i just use only T users array is [User.Type] and it does not conform to Decodable so i can do JSONDecoder().decode . 如果我仅使用T个用户数组,则数组为[User.Type]并且不符合Decodable,因此我可以执行JSONDecoder().decode How should it look ? 看起来怎么样?

Array< User > is not convertible to '[_]?' Array <用户>不能转换为'[_]吗?'

This is because of _ users: [T]? 这是因为_个用户:[T]? type Optional 类型可选

Your method is working fine you just have to define optional array. 您的方法运行良好,您只需要定义可选数组即可。

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

 }

I have created one similar 我创建了一个类似的

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

And call it 并称之为

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

    }

Here is struct 这是结构

struct User :Codable {
    var name:String?
}

Hey Hds you have done most of the work correctly, only one missing point that is knowledge about how Decodables work. 嘿,高清,您已经正确完成了大部分工作,只有一个不足之处是有关“可销毁物品”如何工作的知识。

An array of Decodable is also Decodable. 可解码的数组也是可解码的。 So what I'm trying to say is you don't need to explicitly mention that you want to decode Array<T>.self , you can put T.self as long as you have passed to the function that you are expecting an Array<T>.self so T => Array<T> 因此,我要说的是,您无需明确提及要解码Array<T>.self ,只要将T.self传递给了期望使用Array<T>.self的函数即可Array<T>.self所以T => Array<T>

So in your case when you call this function and pass [User] as the generic parameter, T will be Array<User>.self while decoding. 因此,在您的情况下,当您调用此函数并传递[User]作为通用参数时,解码时T将为Array<User>.self So here is what the code should look like. 所以这是代码的样子。 I'm not sure if the code will 100% compile because I have some missing components, but it gets the idea across. 我不确定代码是否会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)
        }
}

Also I added the do catch block because the try JSONDecoder() throws. 我还添加了do catch块,因为try JSONDecoder()抛出。

Also to add on how you should call the method its like the following: 还要补充如何调用方法,如下所示:

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

}

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM