选项的反思和类型检查

时间:2015-08-12 16:18:58

标签: reflection swift2 typechecking

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

问题:任何项目的镜像中的子数组的每个元素都不是可选的,但是他的类型可以是可选的...当然我会有子值甚至如果值为nil

也许不清楚所以我在这里放了一些代码来解释得更好。

为方便起见,我在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是否为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
}

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

1 个答案:

答案 0 :(得分:0)

根据this answer,我建议使用"addresses": [ { { "metadata": { "source": { "type": "CONTACT", "id": "61327fef08903be4" } }, "formattedValue": "123 Anywhere Street\nSometown", "type": "work", "formattedType": "Work", "streetAddress": "123 Anywhere Street", "city": "Sometown" }]

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

if case Optional<Any>.some(_)