今天我从字典中获取价值时遇到了一个非常奇怪的情况。我在这里提出了两个案例。
情况1
如果我在下面写代码
let str = "{\"num\":2}"
var dict = convertToDictionary(text: str)!
if let num = dict["num"] as? Float {
print("Value is \(num)")
} else {
print("parse error")
}
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
你可以看到关键num
的值是Integer
但是从字典中获取值我期望值为Float
。所以它应该去else块,但它打印的值。
案例2
var test = 2
var dict:[String:Any] = [String:Any]()
dict["num"] = test
if let num = dict["num"] as? Float {
print("Value is \(num)")
} else {
print("parse error")
}
由于我没有定义数据类型,所以默认情况下它应该是整数,我期望值为Float
。这确实有效,因为我预计现在这里是不打印它显示parse error
的价值
请向我解释为什么会这样?
答案是 - 这两个案例中的词典实际上并不完全相同。
在第二种情况下,dict["num"]
类型的Int
值,因为你明确指定了Int
。
但是,在第一种情况下,您可以通过JSONSerialization
获取字典,将数字转换为NSNumber
实例。因此,dict["num"]
的值是NSNumber
类型。用NSNumber
初始化的Int
可以成功地投射到Int
和Float
在第一种情况下,你正在创建json并插入dict
,它以[String: Any]
格式获取值。这里dict["num"]
是NSNumber
格式。
在第二种情况下,您使用dict
格式创建了[String: Any]
,但将值设为Int
。 var test = 2
这一行使变量test
成为Int,当你用格式dict
将该值插入[String: Any]
时,它将Any
格式的值作为Int
。
所以基本上在第二种情况下,dict["num"]
是Int
。
From Apple Doc,变量将采用它在开头分配的值的数据类型。
这就是为什么你可以在第一种情况下将Any转换为Float但在第二种情况下无法将Int转换为Float。
如果你尝试使用var test: Float = 2
,你也会得到第二种情况下的值。
尝试
if let num = dict["num"] as? NSNumber {
let floatValue = num.floatValue
print("Value is \(floatValue)")
} else {
print("parse error")
}