Reflection 选项的反射和类型检查

Reflection 选项的反射和类型检查,reflection,swift2,typechecking,Reflection,Swift2,Typechecking,在swift 2.0中使用反射,我尝试键入检查子值 问题:任何项目镜像中的子数组的每个元素都不是可选的,但其类型可以是可选的。。。发生的事情是,我当然有子值,即使该值为零 可能不清楚,所以我在这里放了一些代码来更好地解释 为了方便起见,我在镜像扩展中定义了一个下标,用于获取具有给定标签的子对象 extension Mirror { public subscript(key: String)->Child?{ var child = children.filter {

在swift 2.0中使用反射,我尝试键入检查子值

问题:任何项目镜像中的子数组的每个元素都不是可选的,但其类型可以是可选的。。。发生的事情是,我当然有子值,即使该值为零

可能不清楚,所以我在这里放了一些代码来更好地解释

为了方便起见,我在镜像扩展中定义了一个下标,用于获取具有给定标签的子对象

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,因此它是nil,并且我无法使用unwrap函数检查他的类型。我正在编写一个反序列化程序,因此我还需要检查var是否为nil,因为在反序列化使用的字典中可以定义它

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
}
我希望问题是清楚的。有什么建议吗?

基于,如果大小写可选,我建议使用

我最近做了一些事情来确保我的结构上至少有一个可选集。您可以粘贴到游乐场:

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: false
struct ErrorResponse:Codable{
让消息:字符串?
let authorizationException:[字符串:字符串]?
让validationException:字符串?
让泛型异常:字符串?
变量isValid:Bool{
var hasAtLeastOneNonNilErrorValue=false
镜子(反射:自我)。孩子们{
如果大小写可选。部分(41;)=$0.0{
HasatEastOnNilErrorValue=true
}
}
返回hasatleastonennilErrorValue
}
}
让errorTest=ErrorResponse(消息:“一些消息”,授权异常:nil,validationException:nil,generalException:nil)
let errorTest2=ErrorResponse(消息:nil,authorizationException:nil,validationException:nil,generalException:nil)
打印(“有效:\(errorTest.isValid)”//有效:真
打印(“有效:\(errorTest2.isValid)”//有效:false

我也遇到了同样的问题,我建议提交一份bug报告。这绝对是坏的。