在以前的版本中,要从 [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中结果是无
无
无
无
。从结果中,我可以学到两点:
1. 当我们使用JSONSerialization
类将JSON数据转换为[String : Any]字典
时,数值被保存为一个NSNumber
对象,但不是 Int
、Double
或 Float
。
2. 在Swift4中,我们可以使用 let float = NSNumberOjbect as? Float
来获取一个Float
值,但是在Swift4.1 中我们不能。但是,我们仍然可以通过这种方式在 Swift4 或 Swift4.1 中获取 Int
或 Double
值。
最后再问一次,这是一个新功能还是一个错误?如果有人知道,你们可以显示公告链接吗?
最佳答案
你需要区分两种情况(在 Swift 3 中,是三种情况):
Any
包含 Swift 原生Double
任何
包含一个NSNumber
(在 Swift 3 中,除了正常的 NSNumber
之外还有 type preserving NSNumber
case。)
当你创建一个原生的 Swift Dictionary
,比如 [String: Any]
,并以正常的方式设置 Double
值时,就像这样你的更新:
let dict: [String : Any] = ["key": 0.1]
在这种情况下,Any
包含表示 Double
的元数据和原始值 0.1
作为 Double
。
并且将持有 Double
的 Any
转换为 Float
总是失败。 As 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
的结果符合这种情况。
在以前的 Swifts 中,(正常的)NSNumber
到 Float
是一个总是成功的操作。
在 Swift 4.1 中,行为随着我在评论中展示的新功能而改变:
SE-0170 NSNumber bridging and Numeric types
在Swift 3中曾经发现过第三种情况,我省略了,它已经过去了。
但是,如何获取 Dictionary
或 Array
以及如何为它们设置值对于解决 Any
问题非常重要> 到 Float
。
最后,这是新功能还是错误?如果有人知道,你们可以显示公告链接吗?
这是一项新功能,不是错误。请参阅上面的链接和下面的相关主题。
关于swift - 在 swift4.1 中将 Any 转换为 Float 总是失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49607492/