我试图解决为什么当涉及到Swift中包含数组的字典时,感觉直观是非法的。
假设我有:
var arr = [1,2,3,4,5]
var dict = ["a":1, "b":2, "test":arr]
我可以像这样轻松访问字典成员:
dict["a"]
dict["b"]
dict["test"]
正如预期的那样,每个都将返回存储的值,包括键的数组" test":
[1,2,3,4,5]
我对此基于其他语言的直观反应是,这应该是合法的:
dict["test"][2]
我期望返回3
。当然,这在Swift中不起作用。经过大量的修补后,我意识到这是正确的方法:
dict["test"]!.objectAtIndex(2)
意识到这一点,我回到我直观的方法并说,"那么,这也应该有效:"
dict["test"]![2]
它做了什么......我真正得到的是为什么解包没有解开暗示的原因。我对Swift"思考的方式缺少什么?"
答案 0 :(得分:4)
Swift中的所有字典查找返回可选变量。
为什么呢?因为您正在查找的密钥可能不存在。如果密钥不存在,则字典返回nil
。由于可以返回nil
,因此查找类型必须是可选。
因为字典查找返回 Optional 值,所以必须将其解包。这可以通过各种方式完成。处理此问题的一种安全方法是使用可选链接并结合可选绑定:
if let value = dict["test"]?[2] {
print(value)
}
在这种情况下,如果"test"
不是有效密钥,则整个链 dict["test"]?[2]
将返回nil
和可选绑定 if let
将失败,因此print
永远不会发生。
如果您强行打开字典访问权限,那么如果密钥不存在则会崩溃:
dict["test"]![2] // this will crash if "test" is not a valid key
答案 1 :(得分:1)
在Objective-C世界中,如果您尝试3
访问dict[@"test"][2]
,则可能会崩溃。如果dict[@"test"]
为零或从dict[@"test"]
获得的数组仅包含两个元素,该怎么办?当然,您已经知道数据就是这样。然后,它完全没有问题。
如果从后端获取数据并且它有一些问题怎么办?这仍将通过编译器,但应用程序在运行时崩溃。用户不是程序员,他们只知道:应用程序崩溃。可能他们不想再使用它了。所以,底线是:根本没有崩溃。
Swift引入了一个名为Optional Type
的类型,这意味着可能缺少值,因此代码在运行时是安全的。在Swift内部,它实际上是在尝试实现if-else
来检查数据是否缺失。
对于您的情况,我将分开两部分:
第1部分:dict["test"]!
告诉编译器忽略if-else
语句并返回值,无论如何。相反,如果值丢失,dict["test"]?
将返回nil
。术语是显式展开
第2部分:dict["test"]?[2]
可能会发生崩溃。如果dict["test"]?
返回一个有效数组且它只有两个元素怎么办?使用Objective-C中的dict[@"test"][2]
,这种存储数据的方式是相同的。这就是为什么它有一个叫做可选类型展开的东西。只有当有效数据存在时,它才会进入if
分支。最安全的方式:
if let element = dict["test"]?[2] {
// do your stuff
}
答案 2 :(得分:1)