看到奇怪的通用行为,这让我相信我在理解中遗漏了一些东西。
我使用以下方法来循环抛出 JSON 响应并调用通用方法。User
、Card
和Ecard
都继承自IDObject
,而又继承自Object
(一个领域类)。
let props:[(label:String, type:IDObject.Type)] = [
(label: "deletedUsers", type: User.self),
(label: "deletedCards", type: Card.self),
(label: "deletedECards", type: Ecard.self)
]
for prop in props {
if let ids = json[prop.label].arrayObject as? [Int], ids.count > 0 {
DataManager.shared.delete(prop.type, ids: ids)
}
}
func delete<T:IDObject>(_ type:T.Type, ids:[Int]) {
guard ids.count > 0 else { return }
if let objectsToDelete = objects(type, where: NSPredicate(format: "identifier IN %@", ids)) {
delete(objectsToDelete)
}
}
func delete<T:Object>(_ objects:Results<T>) {
guard objects.count > 0 else { return }
do {
let realm = try Realm()
try realm.write {
realm.delete(objects)
}
} catch {
print(error)
}
}
delete(_ type:T.Type, ids:[Int])
函数无法以这种方式推断泛型类型。
但是,解开for prop in props
循环的包装按预期工作。
if let userIds = json["deletedUsers"].arrayObject as? [Int], userIds.count > 0 {
DataManager.shared.delete(User.self, ids: userIds)
}
泛型是否仅在编译时工作,或者有没有办法在运行时动态处理这个问题?
泛型在编译时进行评估,并分配一个具体的类型。没有"运行时的类型推断"这样的东西。
我认为您想要的主要更改是:
func delete(_ type:IDObject.Type, ids:[Int]) {
你不想在type
上专门化这个函数,你只想传递type
。
目前尚不清楚objects(_:where:)
返回的内容,因此这可能会破坏您的delete
方法。您可能需要使其不那么具体:
func delete(_ objects:Results<Object>) {
(这不是分型的灵丹妙药;我假设objects(_:where:)
返回的正好Results<Object>
。