选项的反射和类型检查

标签 reflection swift2 typechecking

在 swift 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 尚未初始化,因此为 nil,我无法使用 unwrap 函数检查他的类型。我正在编写一个反序列化器,所以我还需要检查 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
}

我希望问题很清楚。有什么建议?

最佳答案

基于 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: false

关于选项的反射和类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31970553/

相关文章:

java - 如何使用 java 反射返回包含对象以外的内容的集合

尝试在 glassfish 中动态加载类时出现 java.lang.ClassNotFoundException

javascript - 使用 Typescript 声明了一个类型,但 Javascript 在内部使用了错误的类型

java - 从枚举类型和序号中获取枚举值

ios - Swift 2.1 - UIPickerView 不能正常工作

swift - 当不知道该条目的键或值是什么时,使用一个条目访问内部词典(词典的词典)

ios - Swift 2 IBAction 和 Segue

javascript - typescript :有没有办法检查变量是否是具有嵌套属性的接口(interface)定义对象?

python - mypy 提示扩展基类的属性类型

c# - 确定一个类是否被引用 C#