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

LYM*_*LYM 8 downcast swift swift4.1

在以前的版本中,为了从[String: Any]字典中获取浮点值,我可以使用let float = dict["somekey"] as? Float,但在swift4.1中,它不起作用.看来类型dict["somekey"]已经隐含推断为Double之前,我得到它,所以从铸造DoubleFloat总是失败.我想知道这是一个新特征还是一个bug.

- 这是更新.

我重新下载了一个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")
}
Run Code Online (Sandbox Code Playgroud)

在Swift4和Swift4.1的Playground中运行此代码,结果是不同的.在Swift4中,结果是nil 0.2 0.3 0.4,在Swift4.1中得到的结果是nil nil nil nil.从结果,我可以学到两点:1.当我们转换JSON数据转换成[String : Any] dictionaryJSONSerialization类,数值保存为NSNumber目标,而不是Int,DoubleFloat.2.在Swift4中,我们可以使用let float = NSNumberOjbect as? Float获取Float值,但在Swift4.1中我们不能.但是,我们依然可以得到IntDouble以这种方式价值,无论是在Swift4或Swift4.1.最后,这是一个新功能还是一个bug?如果有人知道,你们可以出现公告链接吗?

OOP*_*Per 10

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

  • Any 包含Swift原生 Double
  • Any 含有 NSNumber

(在Swift 3中,除了法线之外还有类型保留NSNumber案例NSNumber.)


当您创建一个原生的Swift,Dictionary例如[String: Any],并Double在更新中以正常方式设置值:

let dict: [String : Any] = ["key": 0.1]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Any保持表示所述元数据Double和原始值0.1作为Double.

和铸造Any控股DoubleFloat总是失败.如DoubleFloat不能与被转换as-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
Run Code Online (Sandbox Code Playgroud)

但是,在Any持有的情况下NSNumber,一如往常发生的时候,Array或者Dictionary是桥接NSArray或者NSDictionary,以前的Swifts和Swift 4.1之间的行为是不同的.

JSONSerialization匹配这种情况的结果.

在以往的雨燕,(正常)NSNumberFloat了一个永远的成功操作.

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

SE-0170 NSNumber桥接和数字类型


我省略了在Swift 3中发现的第三个案例,它已经过去了.

但是,如何通过解决问题来获得您的Dictionary或者Array以及如何设置价值非常重要.AnyFloat


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

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

无法将NSNumber桥接到Float Swift 3.3

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