我正在尝试比较一个类的两个实例的属性。之前我用过这个,它工作正常:
override public func isEqual(_ object: Any?) -> Bool {
if let rhs = object as? BankDataModel, self.accountHolderName == rhs.accountHolderName, self.accountNumber == rhs.accountNumber,
self.accountHolderThirdPartyAccountOwner == rhs.accountHolderThirdPartyAccountOwner, self.bankName == rhs.bankName, self.bankRoutingNumber == rhs.bankRoutingNumber, self.bic == rhs.bic, self.iban == rhs.iban, self.directDebitStatus == rhs.directDebitStatus, self.sepaCreditorID == rhs.sepaCreditorID, self.sepaMandateID == rhs.sepaMandateID{
return true
}else{
return false
}
}
但是如果我想使用它,我必须再次为我的所有模型类写这个。我想要一个可以用于所有模型类的函数,所以我使用了Mirror结构并试过这样的事情:
override public func isEqual(_ object: Any?) -> Bool {
if let rhs = object as? BankDataModel{
return compareTwoObjects(objectToCompare: rhs, objectSelf: self)
}else{
return false
}
}
每个模型中重写的isEqual方法将从Helper类调用此方法,因此我可以在每个模型中使用它:
func compareTwoObjects(objectToCompare: Any, objectSelf: Any) -> Bool{
let objectSelf2 = Mirror(reflecting: objectSelf)
let objectToCompare2 = Mirror(reflecting: objectToCompare)
var index = objectToCompare2.children.startIndex
for attr in objectSelf2.children{
let type1 = Mirror(reflecting: attr.value).subjectType
print(type1)
let type2 = Mirror(reflecting: objectToCompare2.children[index].value).subjectType
print(type2)
if type1 == type2{
print("Equal")
if attr.value as! type1 != objectToCompare2.children[index].value as! type2{
return false
}
}
index = objectToCompare2.children.index(index, offsetBy: 1)
}
return true
}
大多数代码工作正常,当两个变量的类型相等时,print("Equal")
总是执行。
问题是这一行:
if attr.value as! type1 != objectToCompare.children[index].value as! type2{
return false
}
我收到此错误消息:“使用未声明的类型”type1“”。 如果我不使用转换为type1和type2,我得到的错误是我不能使用==两个属性为“Any”的属性。 有没有办法将type1和type2字符串转换为实际数据类型?或者,对于我想要达到的目标,可能有更好的方法吗?
这是我的印刷品输出:
Optional<String>
Optional<String>
Equal
Optional<String>
Optional<String>
Equal
Optional<Bool>
Optional<Bool>
Equal
String
String
Equal
Optional<String>
Optional<String>
Equal
String
String
Equal
String
String
Equal
Optional<DirectDebitStatus>
Optional<DirectDebitStatus>
Equal
我将不胜感激任何帮助!
答案 0 :(得分:2)
Swift 4
我想您可能想要使用Equatable
界面。有了它,你可以实现这样的目标:
extension BankDataModel: Equatable {
static func == (lhs: BankDataModel, rhs: BankDataModel) -> Bool {
return
lhs.accountHolderName == rhs.accountHolderName &&
lhs.accountNumber == rhs.accountNumber &&
lhs.accountHolderThirdPartyAccountOwner == rhs.accountHolderThirdPartyAccountOwner
}
}
注意:您可以使用其他&&
子句扩展return语句,以增加“等于”#check。
然后,只要您放置此扩展程序,就可以使用BankDataModel
运算符将两个==
相互比较,如下所示:
let bankAModel: BankDataModel = // Some model
let bankBModel: BankDataModel = // Also some model
if bankAModel == bankBModel {
// Do stuff
}
<强>扩展强>
我能想到的最好的情况是,您在Equatable
上同时实施了Hashable
和BankDataModel
,以便在Equatable
方面形成一个干净的比较方法(只比较哈希)。
这种方式可以使代码更易于维护和清理。另请参见separation of concerns模式。
答案 1 :(得分:1)
这可能是您正在寻找的内容,它会先将两个Any?
对象首先投放到NSObject
来比较。
private func equalAny<BaseType: Equatable>(lhs: Any?, rhs: Any?, baseType: BaseType.Type) -> Bool {
if (lhs == nil && rhs != nil) || (rhs == nil && lhs != nil) { return false }
if lhs == nil && rhs == nil { return true }
guard let lhsEquatable = lhs as? BaseType, let rhsEquatable = rhs as? BaseType else {
return false
}
return lhsEquatable == rhsEquatable
}
确保使用NSObject
作为基本类型。调用这样的方法:
equalAny(lhs: value, rhs: otherValue, baseType: NSObject.self)