Cast Any中的Cast Any总是在swift4.1中失败

时间:2018-04-02 07:59:24

标签: swift downcast swift4.1

在以前的版本中,要从[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数据转换为[String : Any] dictionaryJSONSerialization时,数值将保存为NSNumber对象,但不会保存为IntDoubleFloat。 2.在Swift4中,我们可以使用let float = NSNumberOjbect as? Float来获取Float值,但在Swift4.1中我们不能。但是,我们仍然可以通过这种方式获得IntDouble值,无论是在Swift4还是Swift4.1中。 最后,这是一个新功能还是一个bug?如果有人知道,你们可以出现公告链接吗?

1 个答案:

答案 0 :(得分:10)

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

  • Any包含Swift原生Double
  • Any包含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

将“Any Double Float转换为Double始终失败。由于Floatas无法使用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,那么当DictionaryNSArrayNSDictionaryJSONSerialization桥接时,总会发生这种情况。 ,前Swifts和Swift 4.1之间的行为不同。

NSNumber的结果符合此情况。

在以前的Swifts中,(正常)FloatDictionary是一个永远成功的操作。

在Swift 4.1中,我在评论中显示的新功能改变了行为:

SE-0170 NSNumber bridging and Numeric types

我省略了在Swift 3中找到的第三个案例,它已经过去了。

但是,如何将ArrayAny以及如何设置值来解决问题FloatIntervalTree非常重要。< / p>

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

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

Unable to bridge NSNumber to Float Swift 3.3

Unexpected behavior when casting an NSNumber to Float