从语义上讲,[String:AnyObject?]
和[String:AnyObject]
就行为方式而言是相同的,这意味着如果我访问未设置和设置的密钥,它们将返回相同的内容nil
的键将从字典中删除该键。为什么他们认为不是同一类型?
var optional = [String:AnyObject?]()
var regular = [String:AnyObject]()
//Some control keys
optional["controlkey"] = "valueoptional"
regular["controlkey"] = "valueRegular"
//Set the keys
optional["keyOptional"] = "valueoptional"
regular["keyRegular"] = "valueRegular"
//Unset the keys
optional["keyOptional"] = nil
regular["keyRegular"] = nil
for (key,val) in optional {
print("key: \(key)\tval: \(val)")
}
for (key,val) in regular {
print("key: \(key)\tval: \(val)")
}
令我惊讶的是,可选的没有打印设置为nil的密钥。 产出如下:
key: controlkey val: Optional(valueoptional) //The keys for the optional dictionary
key: controlkey val: valueRegular //The keys for the `regular` dictionary
为什么我设置为nil的密钥不显示?
答案 0 :(得分:1)
因为从编译器的角度来看,可空类型和非可空类型不是同一个东西。恰好Dictionnary界面最终将它们混合在一起#34;在类似的实体中,但这与Dictionnary实现相关联,而不是类型系统。
编辑:您的更新会更改问题的上下文,但设置为nil是一种不理解我的方法。
答案 1 :(得分:1)
来自Apple文档:
Swift语言定义了后缀?作为语法糖 命名类型可选,在Swift标准中定义 库。
AnyObject类型?是一个包含两种情况的枚举,None和Some(Wrapped),用于表示可能存在或不存在的值。但AnyObject正在响应将要呈现的那个。
为字典中的键设置nil意味着删除元素本身。
尝试设置NSNull()
optional["keyOptional"] = NSNull()
答案 2 :(得分:1)
它们不同,因为您实际上可以将nil
存储到[String:AnyObject?]
中。您不能使用optional[key] = value
(下标运算符)来执行此操作,因为它具有nil
的特殊行为(删除值),但您可以执行此操作:
var optional: [String:AnyObject?] = ["test": nil]
optional.updateValue(nil, forKey: "test2")
print(optional) // ["test2": nil, "test": nil]
当然,从这样的词典中获取一个值:
print(optional["test"]) // Optional(nil)
导致双重可选Optional<Optional<AnyObject>>
(或AnyObject??
)并且与这些类型的交互很麻烦,因此您应该避免将nil
存储到词典中。
答案 3 :(得分:0)
因为设置密钥nil
会从字典中删除该密钥!来自documentation
读取自身中不存在的关键字nil。将nil写为给定键的值将从自身中删除该键
您无法将nil
存储为字典值。如果您需要某些东西来表示虚无,请使用NSNull
:
optional["keyOptional"] = NSNull()
regular["keyRegular"] = NSNull()
答案 4 :(得分:0)
它们的类型不同,因为它们的类型不同;-)编译器就是这样的文字生物。
@Sulthan的答案是正确的,更完整的 - 直到我在自己的答案上发帖后才看到它。但是如果你在[String: AnyObject?]
字典中查找一个键并且存在一个值,你将获得一个包含在一个可选项中的可选项 - 结果是一个AnyObject??
。您必须打开它两次才能使用它:
var optional = [String: AnyObject?]()
// I changed it to NSString because String isn't an AnyObject
v
optional["controlkey"] = NSString(string: "valueoptional")
print(optional["controlkey"]) // prints "Optional(Optional(valueoptional))"
if let val = optional["controlkey"] {
print(val) // prints "Optional(valueoptional)"
if let unwrappedVal = val {
print(unwrappedVal) // prints "valueoptional"
}
}