检查Swift字典扩展中的nil值

Ale*_*311 6 null extension-methods dictionary optional swift

我在playground文件中有以下代码:

extension Dictionary {

    func test()  {

        for key in self.keys {
            self[key]
        }
    }
}

var dict: [String: AnyObject?] = [
    "test": nil
]

dict.test()
Run Code Online (Sandbox Code Playgroud)

我今后将把for-each循环中的行称为输出,因为它是相关的.在这个特定的例子中,输出是nil.

当我将for-each循环更改为如下所示:

for key in self.keys {
    print(self[key])
}
Run Code Online (Sandbox Code Playgroud)

输出是"Optional(nil)\n".

我真正想要做的是检查nil的值,但是代码:

for key in self.keys {
    self[key] == nil
}
Run Code Online (Sandbox Code Playgroud)

输出false.

我尝试的另一件事是:

for key in self.keys {
    self[key] as! AnyObject? == nil
}
Run Code Online (Sandbox Code Playgroud)

产生错误:

Could not cast value of type 'Swift.Optional<Swift.AnyObject>' to 'Swift.AnyObject'
Run Code Online (Sandbox Code Playgroud)

任何帮助都非常感谢!

mat*_*att 7

你已经弄得一团糟了,因为一本字典的价值可以nil呈现给你双重包装的可选性,因此有两种nil.还有就是nil你得到,如果钥匙丢失,然后nil你得到,如果该键缺你解开所取得的结果.不幸的是,你正在一个操场上进行测试,这是一个探索这种区别的糟糕场所.

要了解我的意思,请考虑以下事项:

var d : [String:Int?] = ["Matt":1]
let val = d["Matt"]
Run Code Online (Sandbox Code Playgroud)

是什么类型的val?它是Int??一个包裹在另一个Optional中的可选包装的Int.这是因为该值的字典是,按照定义,一个Int包裹在一个可选的,然后获取其关键包裹,在价值另一可选.

所以现在让我们更进一步,这样做:

var d : [String:Int?] = ["Matt":nil]
let val = d["Matt"]
Run Code Online (Sandbox Code Playgroud)

什么是val?好了,操场上可以nil,但事实是更加复杂; 它nil 包装在另一个Optional中.如果你打印 val,这是最容易看到的,在这种情况下,你得到的不是nil,但是"Optional(nil)".

但是如果我们尝试一下根本没有关键的东西,我们会得到一个不同的答案:

let val2 = d["Alex"]
Run Code Online (Sandbox Code Playgroud)

这确实 nil,表示密钥丢失了.如果我们打印 val2,我们得到"nil".操场上没有作出区分(它说nil的都valval2),但转换为字符串(这是print做)显示的差异.

因此,问题的一部分是整个双重包装的可选项,另一部分是Playground以非常误导的方式表示双重包装的可选项.

MORAL 1:值类型为Optional的字典可能变得非常棘手.

道德2:游乐场是魔鬼的作品.避免他们.使用真实的应用程序,并使用日志记录到控制台或调试器的变量窗格,以查看实际发生的情况.