2017-09-26 192 views
1

有人可以解释的最好的最好的方法找出int型,因为斯威夫特4我有一个JSON这么多的麻烦,因为这奇怪斯威夫特4型系统

enter image description here

原因,这是很普遍的情况,当我试图映射相同的JSON对象到核心数据实体和PONSOs

所以,

id: Int = json["id"] as? Int // works 
id: Int32 = json["id"] as? Int32 // doesn't work 

结果我无法同时满足要求在同一时间。无论如何,我可以避免Swift 4中这种绝对没有意义的int状态吗?

+1

如果您有什么具体的JSON问题,请出示JSON和你的代码正在用它来解析它。 – Sulthan

+1

上面的代码没有显示与JSON相关的任何内容。 '[String:Any]'是“字符串的字典,绝对可以在Swift中表示的任何数据类型。“这通常用于JSON,但用NSJSONSerialization解析JSON不应该生成你在这里给出的字典。上面的任何东西都是”无意义的“,它看起来完全遵循规则,所以它可能有助于解释问题你要解决的问题JSON没有32位或64位的整数类型 –

+0

请注意,Swift的Int匹配ObjC的NSInteger,并且(如ObjC中)是Swift中几乎所有“整数类”事物的推荐类型。除非需要进行低级交互或在32位平台上确保非常大的整数,否则特定的位宽是非常令人沮丧的,它们并不是设计用于Swift中的一般用途;它们设计用于需要非常精确的尺寸和希望在违反尺寸要求时被警告。 –

回答

5

这是令人困惑的原因是因为as?在Swift中有两个完全正交的含义,具体取决于上下文。当斯威夫特类型纯粹处理,as?是一个动态转换,返回非nil只有在类型是字面上对as?运营商的右侧的类型的实例:

import Foundation 

let dict: [String : Any] = ["Foo" : 3 as Int] 

print(dict["Foo"] as? Int) 
print(dict["Foo"] as? Int32) 
print(dict["Foo"] as? Int64) 

这对于返回Optional(3)第一个日志,nil为另外两个,因为类型是Int而不是Int32Int64

然而,当该项目被铸造的类型是Objective-C的类型,那么as?不再是严格的动态转换,而是使桥接行为:

import Foundation 

let dict: [String : Any] = ["Foo" : 3 as NSNumber] 

print(dict["Foo"] as? Int) 
print(dict["Foo"] as? Int32) 
print(dict["Foo"] as? Int64) 

该返回对于所有三个日志,因为这不再是一个动态演员 - 事实上,一个NSNumber实例不是我们尝试投入的三种类型中的任何一种的成员。相反,as?会导致Swift到桥接 Objective-C类型NSNumber,如果可以,则转换为适当的Swift类型。由于Swift具有桥接NSNumberInt,Int32Int64(以及其他数字类型的主机)的逻辑,因此我们得到所有三个日志的Optional(3)。但是,如果您尝试将其转换为类似Decimal的桥接逻辑没有NSNumber桥接逻辑,则仍可获得nil

这方面的一个有趣的副作用是as?没有遵循传递属性:

let foo: Int = 3 
print(foo as? NSNumber as? Int64) // Optional(3) 
print(foo as? Int64)    // nil 

无论如何,如果你投你的价值观NSNumber首先,你应该然后能够从那里转换为任何Objective-C桥梁支持的数字类型,这可能是您的旧Swift 3代码引发的问题。或者,如果你真的知道该值应该是类型,你可以用其他的整数类型初始化之一:

let dict: [String : Any] = ["Foo" : 3 as Int] 

let foo = (dict["Foo"] as? Int).map { Int32($0) }