假设我有一个类,它有很多属性,我想检查它们中的大多数是否为零...
因此,我只想从该检查中排除两个属性(也就是说,针对20个属性进行检查)。
我试过这样的方法:
extension MyClass {
func isEmpty() -> Bool {
let excluded = ["propertyName1", "propertyName2"]
let children = Mirror(reflecting: self).children.filter { $0.label != nil }
let filtered = children.filter {!excluded.map{$0}.contains($0.label)}
let result = filtered.allSatisfy{ $0.value == nil }
return result
}
}
关于这段代码,第一件让我烦恼的事情是,如果我改变一个属性名,我将不得不改变被排除的数组值。
但那并不重要,问题是,这一行:
let result = filtered.allSatisfy{ $0.value == nil }
它不会真正检查属性是否为nil ...编译器警告:
将"Any"类型的非可选值与"nil"进行比较始终返回false
那么,有没有更好/适当的方法来解决这个问题?
1条答案
按热度按时间umuewwlo1#
Mirror
API相当粗糙,Swift的通用反射API还没有设计出来,即使它们已经存在,我也不认为你应该在这种情况下使用它们。字段全为nil的"空示例"的概念实际上没有意义。想象一下
Person(firstName: nil, lastName: nil, age: nil)
。你不会有一个"空的人",你有无意义的废话。如果你需要建模nil,使用nil
:let possiblePerson: Person? = nil
你应该修正你的数据模型。但是如果你现在需要一个解决方案,我有两个想法给你:
∮ ∮只是用无聊的方式∮
或者:
当然,这两种方法都有缺点,即每当添加新属性时都需要进行更新
中间重构
假设您有:
您可以提取出可能为空的部分:
如果属性
a
/b
/c
是您的公共API的一部分,并且您无法轻松更改它们,那么您可以通过添加一些转发计算属性来限制此更改的爆炸半径: