2017-09-26 193 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) }