8

在以前的版本中,要从[String: Any]字典中获取浮点值,我可以使用let float = dict["somekey"] as? Float,但在 swift4.1 中,它不起作用。似乎 of 的类型在我得到它之前dict["somekey"]已经被隐式推断,所以从to 转换总是失败。我想知道这是一个新特性还是只是一个错误。DoubleDoubleFloat

——这里是更新。

我重新下载了一个 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 数据转换为[String : Any] dictionary带有JSONSerialization类的 a 时,数值被保存为NSNumber对象,而不是Int,DoubleFloat。2. 在Swift4中,我们可以使用let float = NSNumberOjbect as? Float来获取一个Float值,但是在Swift4.1中我们不能。但是,我们仍然可以通过这种方式获取IntDouble赋值,无论是在 Swift4 还是 Swift4.1 中。最后,这是一个新功能还是一个错误?如果有人知道,你们可以显示公告链接吗?

4

1 回答 1

10

您需要区分两种情况(在 Swift 3 中是三种情况):

  • Any包含 Swift 本机Double
  • Any包含一个NSNumber

(在 Swift 3 中,除了普通的 .,还有其他类型保留的NSNumber情况NSNumber。)


当您创建本机 Swift 时Dictionary,例如, 并在更新中像这样以正常方式[String: Any]设置值:Double

let dict: [String : Any] = ["key": 0.1]

在这种情况下,Any将表示的元数据Double和原始值保存0.1Double.

并且铸造Any控股总是失败DoubleFloat至于Double不能Floatas-castings 转换。

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持有的情况下,就像从or桥接orNSNumber时总是发生的那样,以前的 Swift 和 Swift 4.1 之间的行为是不同的。ArrayDictionaryNSArrayNSDictionary

的结果JSONSerialization匹配这种情况。

在以前的 Swift 中,(正常)NSNumbertoFloat是一个总是成功的操作。

在 Swift 4.1 中,行为随着我在评论中展示的新功能而改变:

SE-0170 NSNumber 桥接和数字类型


我省略了在 Swift 3 中发现的第三种情况,它已经过去了。

但是,如何获得DictionaryorArray以及如何为它们设置值以解决问题Any非常重要Float


最后,这是一个新功能还是一个错误?如果有人知道,你们可以显示公告链接吗?

这是一个新功能,而不是一个错误。请参阅上面的链接,以及下面的相关主题。

无法将 NSNumber 桥接到 Float Swift 3.3

将 NSNumber 转换为 Float 时出现意外行为

于 2018-04-07T03:14:04.827 回答