2015-12-31 63 views
1

是否有任何簡單的方法在Swift中將任何IntegerType轉換爲Int。我有一個包含不同類型整數的字典; UInt8,UInt16等,並需要將其轉換爲Int。有沒有除了switch語句的任何簡單的方法:Swift - 將任何IntegerType轉換爲Int

let x: UInt8 = 5 
let any: Any = x 

var size: Int 
switch (any) { 
case let value as Int8: size = Int(value) 
case let value as UInt8: size = Int(value) 
case let value as Int16: size = Int(value) 
case let value as UInt16: size = Int(value) 
case let value as Int32: size = Int(value) 
case let value as UInt32: size = Int(value) 
case let value as Int64: size = Int(value) 
case let value as UInt64: size = Int(value) 
case let value as Int: size = Int(value) 
case let value as UInt: size = Int(value) 
default: size = 0 
} 
+0

你可以隨時使用任何IntegerType的hashValue屬性 –

+0

這可能會工作,但是如何將Any轉換爲IntegerType? –

+0

if let int =(any as?UInt8)?hashValue {print(int) } –

回答

2

你的問題是,你允許Any接觸到的圖片。那時,你失去了很多力量。

你面對的另一個問題是,你寫的代碼定義不好,Swift拒絕你用這種方式編寫代碼(基本上是通過強迫你明確)。如果您通過了UInt64,則不能保證size將具有與value相同的值。當人們尋求在數字類型之間進行轉換的自動方式時,這是一個非常常見的問題。 Swift鼓勵您考慮數字轉換,因爲它們是錯誤的常見來源。

根據你想要解決的問題,你可以做幾件事情。如果你想要一個包含Int64或UInt64的數據結構,那很簡單。只需創建你的意思。

enum ParsedNumber { 
    case Signed(Int64) 
    case Unsigned(UInt64) 
} 

let numbers: [String: ParsedNumber] = [:] 

然後你所有的價值觀都適合。如果以後需要跟蹤寬度,那麼這也是沒有問題的:

struct ParsedNumber { 
    enum Value { 
     case Signed(Int64) 
     case Unsigned(UInt64) 
    } 
    let width: Int 
    let value: Value 
} 

let n = ParsedNumber(width: 32, value: .Signed(2)) 

這就好像你正在解決的問題。如果在另一方面,你在一個點上知道你的類型(即它Int8,不Any),只是希望能夠將它傳遞給函數,只是使通用功能上IntegerType

func calc<Num: IntegerType>(num: Num) { ... } 

一個有用的工具IntegerType是其toIntMax()方法。如果值太大,這會陷入(崩潰),因此請注意,但是將任意值轉換爲已知整數類型是一種有用的方法。如果您已經知道您的標誌,還有SignedIntegerTypeUnsignedIntegerType。 (你不能將Any轉換成這些,但是你需要在某處已經有一個已知的類型。)

+0

謝謝,我明白你的觀點。我想我可以將這個想法擴展到其他類型,如浮動,字符串。 –

+0

是的。像你這樣的解析器幾乎可以肯定地想要吐出某種枚舉,將其結果限制爲可解析的類型,並將它們打包以便於其他程序的方便使用。請記住,枚舉可以有自己的方法,所以在枚舉上創建'isString:Bool'或'stringValue:String?'很容易,因此如果不需要它們,可以在不需要switch語句的情況下使用它。 –