2015-11-25 90 views
0

我想要什麼我可以使用泛型將NSNumber快速轉換爲T嗎?

func safeGet<T>() -> T { 
    let value = magic() 
    if let typedValue = value as? T { 
     return typedValue 
    } 
} 

這不工作的原因是,你不能迅速

我放什麼<what do I put here?>佔位做<NSNumber> as Int

func safeGet<T>() -> T { 
    let value = magic() 
    if let typedValue = value as? NSNumber { 
     return <what do I put here?> 
    } else if let typedValue = value as? T { 
     return typedValue 
    } 
} 
+0

我已經試過'T(的TypedValue)'和'的TypedValue如! T' – Pylinux

+2

我不確定你可以將它作爲一個通用的(至少在不失去準確性/信息的情況下)爲了從'NSNumber'中獲取值,你需要使用特定於類型的函數,如'doubleValue '和'boolValue'。做它作爲一個協議和擴展集合可能是一個更好的方法。這也可以讓你實現更有用的類型轉換。 –

回答

2

最後,我做到了這一點,以便能夠以引發錯誤的方式從字典中獲取類型化值。它這樣使用

let name:String = dictionary.safeGet("name") 

let name = dictionary.safeGet("name") as String` 

的源代碼:


進口基金會

extension Dictionary { 
    func safeGet<T>(key:Key) throws -> T { 
     if let value = self[key] as? AnyObject { 
      if let typedValue = value as? T { 
       return typedValue 
      } 

      let typedValue: T? = parseNumber(value) 
      if typedValue != nil { 
       return typedValue! 
      } 

      let typeData = Mirror(reflecting: value) 
      throw generateNSError(
       domain: "DictionaryError.WrongType", 
       message: "Could not convert `\(key)` to `\(T.self)`, it was `\(typeData.subjectType)` and had the value `\(value)`" 
      ) 
     } else { 
      throw generateNSError(
       domain: "DictionaryError.MissingValue", 
       message: "`\(key)` was not in dictionary. The dictionary was:\n\(self.description)" 
      ) 
     } 
    } 

    private func parseNumber<T>(value: AnyObject) -> T? { 
     if Int8.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.charValue as? T 
      } else if let stringValue = value as? String { 
       return Int8(stringValue) as? T 
      } 
     } else if Int16.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.shortValue as? T 
      } else if let stringValue = value as? String { 
       return Int16(stringValue) as? T 
      } 
     } else if Int32.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.longValue as? T 
      } else if let stringValue = value as? String { 
       return Int32(stringValue) as? T 
      } 
     } else if Int64.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.longLongValue as? T 
      } else if let stringValue = value as? String { 
       return Int64(stringValue) as? T 
      } 
     } else if UInt8.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.unsignedCharValue as? T 
      } else if let stringValue = value as? String { 
       return UInt8(stringValue) as? T 
      } 
     } else if UInt16.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.unsignedShortValue as? T 
      } else if let stringValue = value as? String { 
       return UInt16(stringValue) as? T 
      } 
     } else if UInt32.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.unsignedIntValue as? T 
      } else if let stringValue = value as? String { 
       return UInt32(stringValue) as? T 
      } 
     } else if UInt64.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.unsignedLongLongValue as? T 

      } else if let stringValue = value as? String { 
       return UInt64(stringValue) as? T 
      } 
     } else if Double.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.doubleValue as? T 
      } else if let stringValue = value as? String { 
       return Double(stringValue) as? T 
      } 
     } else if Float.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.floatValue as? T 
      } else if let stringValue = value as? String { 
       return Float(stringValue) as? T 
      } 
     } else if String.self == T.self { 
      if let numericValue = value as? NSNumber { 
       return numericValue.stringValue as? T 
      } else if let stringValue = value as? String { 
       return stringValue as? T 
      } 
     } 
     return nil 
    } 

    private func generateNSError(domain domain: String, message: String) -> NSError { 
     return NSError(
      domain: domain, 
      code: -1, 
      userInfo: [ 
       NSLocalizedDescriptionKey: message 
      ]) 
    } 
} 
相關問題