我有以下 Swift 通用方法:
static func getRecords<T>(_ which: Which, from table: Table, completionHandler: @escaping ([T]) -> Void)
{
let url: String = DatabaseInterface.getUrl(which, from: table)
Http.get(url: url)
{
response, error in
if nil != error
{
print("get\(table.rawValue)() failed; error = \(error!)")
return
}
var objects: [T] = []
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd" // Matches PHP's "Y-m-d" \Date format.
let records = (response!["records"])!
for record in (records as! [NSDictionary])
{
// This line fails with the error
// 'T' cannot be constructed because it has no accessible initializers
objects.append(T(fromDictionary: record as! [String: Any]))
}
DispatchQueue.main.async
{
completionHandler(objects)
}
}
}
Http.get() 方法从服务器检索记录并将 JSON 解码为字典数组。
objects.append() 行失败并显示以下错误:
无法构造“T”,因为它没有可访问的初始值设定项
我的第一个问题:是否可以在泛型函数中创建由类型占位符指定的类型的新实例?
我的第二个问题:如果可能的话,这样做的正确语法是什么?
编译器不知道 T 有初始值设定项。您需要将其限制为包含 init(fromDictionary:) 的协议或类
protocol JSONInitializable {
init(fromDictionary: [String: Any])
}
static func getRecords<T: JSONInitializable>(
_ which: Which,
from table: Table,
completionHandler: @escaping ([T]) -> Void
) {
let url = DatabaseInterface.getUrl(which, from: table)
Http.get(url: url) { _response, error in
guard let response = _response as? [String: [[String: Any]]],
error == nil else {
print("get\(table.rawValue)() failed; error = \(error!)")
return
}
guard let objects = response["records"]?.map(T.init(fromDictionary:)) {
fatalError("`response` doesn't have a value for the key \"records\".")
}
DispatchQueue.main.async { completionHandler(objects) }
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句