Swift 有没有更好的方法从字典(JSON数据)中获取数字?

Swift 有没有更好的方法从字典(JSON数据)中获取数字?,swift,dictionary,casting,Swift,Dictionary,Casting,假设我接收到一些JSON格式的数据,然后使用本机工具将其解析到字典中。其中一些值是数字,我自然需要解析它们,将它们转换为我在应用程序中需要的内容 但是从Any到实际数字的转换,例如Float,Int,Double,似乎有点混乱。例如,如果我期望一个double,但在某个点上服务器返回一个整数,那么我的代码将失败,使用: let doubleValue = dictionary["key"] as! Double 因此,当项目为1.3时,这将起作用,但当项目为1时,这将失败。要使用更具体的示例,

假设我接收到一些JSON格式的数据,然后使用本机工具将其解析到字典中。其中一些值是数字,我自然需要解析它们,将它们转换为我在应用程序中需要的内容

但是从
Any
到实际数字的转换,例如
Float
Int
Double
,似乎有点混乱。例如,如果我期望一个double,但在某个点上服务器返回一个整数,那么我的代码将失败,使用:

let doubleValue = dictionary["key"] as! Double
因此,当项目为
1.3
时,这将起作用,但当项目为
1
时,这将失败。要使用更具体的示例,我们可以使用以下内容:

let myDictionary: [String: Any] = [
    "myNumber_int" : 1,
    "myNumber_float" : Float(1),
    "myNumber_cgFloat" : CGFloat(1),
    "myNumber_double" : 1.0
]

let numberInt1 = myDictionary["myNumber_int"] as? Int // 1
let numberInt2 = myDictionary["myNumber_int"] as? Float // nil
let numberInt3 = myDictionary["myNumber_int"] as? CGFloat // nil
let numberInt4 = myDictionary["myNumber_int"] as? Double // nil

let numberFloat1 = myDictionary["myNumber_float"] as? Int // nil
let numberFloat2 = myDictionary["myNumber_float"] as? Float // 1
let numberFloat3 = myDictionary["myNumber_float"] as? CGFloat // nil
let numberFloat4 = myDictionary["myNumber_float"] as? Double // nil

let numberCGFloat1 = myDictionary["myNumber_cgFloat"] as? Int // nil
let numberCGFloat2 = myDictionary["myNumber_cgFloat"] as? Float // nil
let numberCGFloat3 = myDictionary["myNumber_cgFloat"] as? CGFloat // 1
let numberCGFloat4 = myDictionary["myNumber_cgFloat"] as? Double // nil

let numberDouble1 = myDictionary["myNumber_double"] as? Int // nil
let numberDouble2 = myDictionary["myNumber_double"] as? Float // nil
let numberDouble3 = myDictionary["myNumber_double"] as? CGFloat // nil
let numberDouble4 = myDictionary["myNumber_double"] as? Double // 1
因此,对于每种类型,只有1个cast实际起作用,这是。。。嗯,我至少希望
CGFloat
能够直接转换为
Double
Float

因此,我的解决方案是使用
NSNumber

let myNumbers: [CGFloat] = [
    CGFloat((myDictionary["myNumber_int"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_float"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_cgFloat"] as? NSNumber)?.floatValue ?? 0.0),
    CGFloat((myDictionary["myNumber_double"] as? NSNumber)?.floatValue ?? 0.0),
] // [1,1,1,1]
这是很自然的,但是对于像这样简单的东西来说,代码非常难看。但把“丑陋”的代码放在一边;如果不使用下一步,我们不能做类似的事情吗?我的意思是
NSNumber
对于像这样看似微不足道的事情?我在这里遗漏了一些非常明显的东西,对吗?

试着这样做:-

if let data = myDictionary as? [String: AnyObject] {
    let myNumber = data["myNumber_int"] as? Int
}

您是否必须“使用本机工具”解析JSON?你不能使用
JSONDecoder
Codable
吗?当你从某处得到
JSON
时,整数值是
Int
,流动点值是
双精度
,句点。如果你的解析器创建了更多的类型,使用更好的解析器或者考虑清扫者的建议。@ VADEN我道歉如果JSON的东西让你迷惑,但它更像是一个例子。但是,即使只有整数和浮点数,问题仍然存在。如果使用具体类型创建字典,则即使将字典声明为
[String:Any]
,类型仍然存在。同样,接收到的JSON只有两种类型。您甚至可以将
1
转换为
Double
(当然,反之亦然)。您应该在
Swift
语言中使用
Any
Any
用于非对象或
Swift
中的所有类型,因此
Int
Double
Float
数组
字典
中的非对象<代码>任何对象用于
实例。一个问题是,如果你不知道价值的类型,那么你为什么要铸造。只有
让numberprint2=myDictionary[“myNumber\u int”]
肯定会有用。有趣。显然,没有机会将整本词典转换为其他类型,但以下内容确实有效:
(myDictionary[“myNumber\u int”]as?AnyObject)as?Float
。它仍然很难看,如果我错了,请纠正我,但是
任何对象
不是为ObjectiveC桥设计的吗?如果字典没有任何价值,它也将帮助您进行零处理。。。若你们有一个字典数组,那个么就创建一个模型来获取结构数据。它确实有效,我只是在一个操场上测试了它。我只是不完全明白为什么。。。在这种情况下,任何对象和任何对象之间有什么主要区别我想我知道会发生什么。。。通过这样做,您可以桥接到Objective,Objective现在可以自动将所有原语转换为
NSNumber
。现在,
NSNumber
可以自动转换为Swift中的任何原语。我在初始字典中使用了
“myNumber\u int”:NSNumber(值:1.0)
,并在第一部分中使用了所有返回值(所有值都已正确转换)。因此,基本上,第一个演员是自动为我们在这种情况下,没有更多。但如果可能的话,我想避免使用Objective和
NSNumber