在迅捷2.0中玩反射,我正在尝试键入检查子值。
问题:任何项的镜像中的子数组中的每个元素都不是可选的,但是它的类型可以是可选的.当然,即使值为零,我也有子值。
也许还不清楚,所以我在这里放了一些代码来更好地解释。
为了方便起见,我在Mirror扩展中定义了一个下标,它用给定的标签获取子对象
extension Mirror {
public subscript(key: String)->Child?{
var child = children.filter {
var valid = false
if let label = $0.label {
valid = label == key
}
return valid
}.last
if child == nil,
let superMirror = superclassMirror() {
child = superMirror[key]
}
return child
}
}太好了,假设我有这门课
class Rule: NSObject, AProtocol {
var hello: String?
var subRule: Rule?
}好吧,现在问题是
let aRule = Rule()
let mirroredRule = Mirror(reflecting:aRule)
if let child = mirroredRule["subRule"] {
//child.value always exists
//i can't do child.value is AProtocol? because child.value is not optional
//child.value is AProtocol of course returns false
//child.dynamicType is Optional(Rule)
if let unwrapped = unwrap(child.value) where unwrapped is AProtocol {
//This of course works only if child.value is not nil
//so the unwrap function returns an unwrapped value
//this is not a definitive solution
}
}child.value还没有初始化,所以它是零,而且我无法使用解包装函数检查他的类型。我正在编写反序列化器,所以我也需要检查var是否为空,因为在将用于反序列化的字典中可以定义它。
private func unwrap(subject: Any) -> Any? {
var value: Any?
let mirrored = Mirror(reflecting:subject)
if mirrored.displayStyle != .Optional {
value = subject
} else if let firstChild = mirrored.children.first {
value = firstChild.value
}
return value
}我希望问题是清楚的。有什么建议吗?
发布于 2017-12-11 17:15:17
基于this answer,我建议使用if case Optional<Any>.some(_)。
最近我做了一些事情,以确保至少有一个可选的设置在我的结构上。你可以粘贴到操场:
struct ErrorResponse: Codable {
let message: String?
let authorizationException: [String: String]?
let validationException: String?
let generalException: String?
var isValid: Bool {
var hasAtLeastOneNonNilErrorValue = false
Mirror(reflecting: self).children.forEach {
if case Optional<Any>.some(_) = $0.value {
hasAtLeastOneNonNilErrorValue = true
}
}
return hasAtLeastOneNonNilErrorValue
}
}
let errorTest = ErrorResponse(message: "some message", authorizationException: nil, validationException: nil, generalException: nil)
let errorTest2 = ErrorResponse(message: nil, authorizationException: nil, validationException: nil, generalException: nil)
print("is valid: \(errorTest.isValid)") //is valid: true
print("is valid: \(errorTest2.isValid)") //is valid: falsehttps://stackoverflow.com/questions/31970553
复制相似问题