在以前的版本中,要从[String: Any]
字典中获取浮点值,我可以使用let float = dict["somekey"] as? Float
,但在swift4.1中,它不起作用。似乎在我得到它之前,dict["somekey"]
的类型已经被隐含地推断为Double
,所以从Double
到Float
的铸造总是失败的。我想知道这是一个新特征还是只是一个错误。
--这是更新。
我重新下载了Xcode9.2并做了一些实验,现在我想我弄清楚发生了什么。以下是测试代码:
let dict: [String : Any] = ["key": 0.1]
if let float: Float = dict["key"] as? Float {
print(float)
} else {
print("nil")
}
let dict1: [String : Any] = ["key": NSNumber(value: 0.2)]
if let float: Float = dict1["key"] as? Float {
print(float)
} else {
print("nil")
}
let number = NSNumber(value: 0.3)
if let float: Float = number as? Float {
print(float)
} else {
print("nil")
}
let number1 = NSNumber(floatLiteral: 0.4)
if let float = number1 as? Float {
print(float)
} else {
print("nil")
}
在 Swift4 和 Swift4.1 的 Playground 中运行此代码,结果是不同的。在 Swift4 中,结果是nil
0.2
0.3
0.4
的,而在 Swift4.1 中,结果是nil
nil
nil
nil
的。从结果中,我可以学到两点: 1.当我们将JSON数据转换为带有JSONSerialization
类的[String : Any] dictionary
时,数值将保存为NSNumber
对象,而不是Int
,Double
或Float
。 2. 在 Swift4 中,我们可以使用let float = NSNumberOjbect as? Float
来获取Float
值,但在 Swift4.1 中我们不能。但是,我们仍然可以通过这种方式获得Int
或Double
值,无论是在 Swift4 还是 Swift4.1 中。 最后,这是一个新功能还是一个错误?如果有人知道,你们可以显示公告链接吗?
你需要区分两种情况(在 Swift 3 中,它是三种情况):
- 包含 Swift 原生
Double
Any
- 包含
NSNumber
的Any
(在 Swift 3 中,除了正常NSNumber
之外,还有NSNumber
类型保留的情况。
当您创建本机 SwiftDictionary
(如[String: Any]
)并在更新中以正常方式设置Double
值时:
let dict: [String : Any] = ["key": 0.1]
在这种情况下,Any
将表示Double
的元数据和原始值0.1
保存为Double
。
而将Double
投掷Any
Float
总是失败的。由于Double
到Float
不能用as
铸件进行转换。
let dblValue: Double = 0.1
if let fltValue = dblValue as? Float { //<-Cast from 'Double' to unrelated type 'Float' always fails
print(fltValue)
} else {
print("Cannot convert to Float")
}
//->Cannot convert to Float
但是,在Any
持有NSNumber
的情况下,当Array
或Dictionary
从NSArray
或NSDictionary
桥接时,以前的 Swifts 和 Swift 4.1 的行为是不同的。
JSONSerialization
的结果与此情况相符。
在前雨燕队,(正常的)NSNumber
Float
是一次永远成功的行动。
在 Swift 4.1 中,行为随着我在评论中显示的新功能而改变:
SE-0170 NSNumber 桥接和数值类型
我省略了在 Swift 3 中发现的第三个案例,它已经过去了。
但是,如何获得Dictionary
或Array
以及如何为它们设置值,以解决问题Any
Float
非常重要。
最后,这是一个新功能还是一个错误?如果有人知道,你们可以显示公告链接吗?
这是一个新功能,而不是错误。请参阅上面的链接以及下面的相关主题。
无法将 NSNumber 桥接到 Float Swift 3.3
将 NSNumber 转换为浮点数时出现意外行为