最後,我做到了這一點,以便能夠以引發錯誤的方式從字典中獲取類型化值。它這樣使用
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
])
}
}
我已經試過'T(的TypedValue)'和'的TypedValue如! T' – Pylinux
我不確定你可以將它作爲一個通用的(至少在不失去準確性/信息的情況下)爲了從'NSNumber'中獲取值,你需要使用特定於類型的函數,如'doubleValue '和'boolValue'。做它作爲一個協議和擴展集合可能是一個更好的方法。這也可以讓你實現更有用的類型轉換。 –