是否可以将 Any 转换为 Optional?
Is it possible to cast Any to an Optional?
假设我有一段这样的代码:
let x: Int? = 10
let y: Any = x
现在我想将 y 转换为 Int?:
let z = y as Int? // Error: Cannot downcast from 'Any' to a more optional type 'Int?'
这是不可能的还是有其他方法?
您可以这样做以获得任意选项
func unwrap(any:Any) -> Any? {
let mi:MirrorType = reflect(any)
if mi.disposition != .Optional {
return any
}
if mi.count == 0 { return nil } // Optional.None
let (name,some) = mi[0]
return some.value
}
所以在你的情况下,
let z = unwrap(y) as? Int
参考:
对于Swift 2.0,您可以使用以下内容:
let x: Int? = 10
let y: Any = x
let z = Mirror(reflecting: y).descendant("Some") as? Int
或作为函数:
func castToOptional<T>(x: Any) -> T? {
return Mirror(reflecting: x).descendant("Some") as? T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
或者,如果您不喜欢反射,也可以这样做:
func castToOptional<T>(x: Any) -> T {
return x as! T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
func castAsOptionalInt(value: Any)->Int? {
let mirror = Mirror(reflecting:value)
if mirror.subjectType == Optional<Int>.self {
let ret = mirror.children.first?.1
return ret as? Int
} else {
return nil
}
}
let x: Int? = 10
let y: Any = x
let z = castAsOptionalInt(y) // 10
let a: Double? = 10
let b: Any = a
let c = castAsOptionalInt(b) // nil
这个解决方案怎么样,我做了一个以前答案的通用版本。
fileprivate func unwrap<T>(value: Any)
-> (unwraped:T?, isOriginalType:Bool) {
let mirror = Mirror(reflecting: value)
let isOrgType = mirror.subjectType == Optional<T>.self
if mirror.displayStyle != .optional {
return (value as? T, isOrgType)
}
guard let firstChild = mirror.children.first else {
return (nil, isOrgType)
}
return (firstChild.value as? T, isOrgType)
}
let value: [Int]? = [0]
let value2: [Int]? = nil
let anyValue: Any = value
let anyValue2: Any = value2
let unwrappedResult:([Int]?, Bool)
= unwrap(value: anyValue) // ({[0]}, .1 true)
let unwrappedResult2:([Int]?, Bool)
= unwrap(value: anyValue2) // (nil, .1 true)
let unwrappedResult3:([UInt]?, Bool)
= unwrap(value: anyValue) // (nil, .1 false)
let unwrappedResult4:([NSNumber]?, Bool)
= unwrap(value: anyValue) ({[0]}, .1 false)
以下是Playground上的代码。
如果有人正在寻找即插即用的词典解决方案,可以这样:
extension Dictionary where Value == Any {
func typedValue<T>(forKey key: Key) -> T? {
if let anyValue: Any = self[key] {
return (anyValue as! T)
}
return nil
}
func optionalTypedValue<T>(forKey key: Key) -> T?? {
return self.typedValue(forKey: key)
}
}
假设我有一段这样的代码:
let x: Int? = 10
let y: Any = x
现在我想将 y 转换为 Int?:
let z = y as Int? // Error: Cannot downcast from 'Any' to a more optional type 'Int?'
这是不可能的还是有其他方法?
您可以这样做以获得任意选项
func unwrap(any:Any) -> Any? {
let mi:MirrorType = reflect(any)
if mi.disposition != .Optional {
return any
}
if mi.count == 0 { return nil } // Optional.None
let (name,some) = mi[0]
return some.value
}
所以在你的情况下,
let z = unwrap(y) as? Int
参考:
对于Swift 2.0,您可以使用以下内容:
let x: Int? = 10
let y: Any = x
let z = Mirror(reflecting: y).descendant("Some") as? Int
或作为函数:
func castToOptional<T>(x: Any) -> T? {
return Mirror(reflecting: x).descendant("Some") as? T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
或者,如果您不喜欢反射,也可以这样做:
func castToOptional<T>(x: Any) -> T {
return x as! T
}
let x: Int? = 10
let y: Any = x
let z: Int? = castToOptional(y)
func castAsOptionalInt(value: Any)->Int? {
let mirror = Mirror(reflecting:value)
if mirror.subjectType == Optional<Int>.self {
let ret = mirror.children.first?.1
return ret as? Int
} else {
return nil
}
}
let x: Int? = 10
let y: Any = x
let z = castAsOptionalInt(y) // 10
let a: Double? = 10
let b: Any = a
let c = castAsOptionalInt(b) // nil
这个解决方案怎么样,我做了一个以前答案的通用版本。
fileprivate func unwrap<T>(value: Any)
-> (unwraped:T?, isOriginalType:Bool) {
let mirror = Mirror(reflecting: value)
let isOrgType = mirror.subjectType == Optional<T>.self
if mirror.displayStyle != .optional {
return (value as? T, isOrgType)
}
guard let firstChild = mirror.children.first else {
return (nil, isOrgType)
}
return (firstChild.value as? T, isOrgType)
}
let value: [Int]? = [0]
let value2: [Int]? = nil
let anyValue: Any = value
let anyValue2: Any = value2
let unwrappedResult:([Int]?, Bool)
= unwrap(value: anyValue) // ({[0]}, .1 true)
let unwrappedResult2:([Int]?, Bool)
= unwrap(value: anyValue2) // (nil, .1 true)
let unwrappedResult3:([UInt]?, Bool)
= unwrap(value: anyValue) // (nil, .1 false)
let unwrappedResult4:([NSNumber]?, Bool)
= unwrap(value: anyValue) ({[0]}, .1 false)
以下是Playground上的代码。
如果有人正在寻找即插即用的词典解决方案,可以这样:
extension Dictionary where Value == Any {
func typedValue<T>(forKey key: Key) -> T? {
if let anyValue: Any = self[key] {
return (anyValue as! T)
}
return nil
}
func optionalTypedValue<T>(forKey key: Key) -> T?? {
return self.typedValue(forKey: key)
}
}