Swift 泛型功能与转义闭包



我有方法:

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] 并且它不符合可解码,所以我可以做JSONDecoder().decode.它应该是什么样子?

数组<用户>不能转换为"[_]?

这是因为_ 用户:[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 User :Codable {
var name:String?
}

嘿,HDS,您已经正确完成了大部分工作,唯一缺少的一点是有关Decodables如何工作的知识。

可解码数组也是可解码的。所以我想说的是,你不需要明确提到你想解码Array<T>.self,你可以把T.self,只要你已经传递给你期待一个Array<T>.self的函数,所以T =>Array<T>

因此,在您调用此函数并将[User]作为泛型参数传递时,解码时将TArray<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
}

希望这有帮助。

最新更新