如何编写处理可选值的Dictionary扩展

Rob*_*Rob 10 swift swift-dictionary

我正在尝试实现Dictionary扩展,我想处理可选值.但无论我做什么,如果我在[String: String?]字典上使用我的方法,它都无法选择性地绑定值.如何编写优雅处理可选值的字典的扩展?


考虑以下扩展:

extension Dictionary {
    func someMethod() {
        for (key, value) in self {
            if let valueString = value as? String {
                println("  \(key) = \(valueString)")
            } else {
                println("  \(key) = \(value) cannot be cast to `String`")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请考虑以下代码:

let dictionary: [String: AnyObject?] = ["foo": "bar"]
dictionary.someMethod()
Run Code Online (Sandbox Code Playgroud)

它好奇地报道

foo = Optional(bar) cannot be cast to `String`
Run Code Online (Sandbox Code Playgroud)

我可以编写一个非扩展方法来处理带有可选值的字典参数,但是看不到如何将它作为扩展名来实现Dictionary.

Ben*_*ane 4

你可以通过反思来做到这一点。不需要比您已有的代码更多的代码:

extension Dictionary
{
    func someMethod()
    {
        for (key, value) in self
        {
            var valueRef = _reflect(value)

            while valueRef.disposition == .Optional && valueRef.count > 0 && valueRef[0].0 == "Some"
            {
                valueRef = valueRef[0].1
            }

            if let valueString: String = valueRef.value as? String
            {
                print("  \(key) = \(valueString)")
            }
            else
            {
                print("  \(key) = \(value) cannot be cast to `String`")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
let dictionary: [String : AnyObject?] = ["foo" : "bar"]
dictionary.someMethod()
Run Code Online (Sandbox Code Playgroud)

退货

extension Dictionary
{
    func someMethod()
    {
        for (key, value) in self
        {
            var valueRef = _reflect(value)

            while valueRef.disposition == .Optional && valueRef.count > 0 && valueRef[0].0 == "Some"
            {
                valueRef = valueRef[0].1
            }

            if let valueString: String = valueRef.value as? String
            {
                print("  \(key) = \(valueString)")
            }
            else
            {
                print("  \(key) = \(value) cannot be cast to `String`")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
let dictionary: [String : AnyObject?] = ["foo" : nil]
dictionary.someMethod()
Run Code Online (Sandbox Code Playgroud)

退货

let dictionary: [String : AnyObject?] = ["foo" : "bar"]
dictionary.someMethod()
Run Code Online (Sandbox Code Playgroud)
let dictionary: [String : AnyObject?] = ["foo" : UIViewController()]
dictionary.someMethod()
Run Code Online (Sandbox Code Playgroud)

退货

foo = bar
Run Code Online (Sandbox Code Playgroud)