您可以通过添加伪协议和使用is
for类型检查来检查可选类型,然后Mirror(..)
从可选中提取实际类型值Any
:
protocol IsOptional {} extension Optional : IsOptional {} /* Detect if any is of type optional */ let any: Any = Optional("123") var object : AnyObject? = nil switch any { case is IsOptional: print("is an optional") if let (_, a) = Mirror(reflecting: any).children.first { object = a as? AnyObject } default: print("is not an optional") } /* Prints "is an optional" */ /* Detect if any2 is of type optional */ let any2: Any = String("123") switch any2 { case is IsOptional: print("is an optional") // ... default: print("is not an optional") } /* Prints "is not an optional" */
Charlie Monroes自己的最终解决方案非常简洁(+1!).我想我会添加一个补充.
鉴于_XUOptional
已经定义了协议并对其进行了Optional
类型扩展(如Charlies的回答),您可以any
使用可选链接和nil合并运算符处理可选或不在一行中的事件:
let anyOpt: Any = Optional("123") let anyNotOpt: Any = String("123") var object: AnyObject? object = (anyOpt as? _XUOptional)?.objectValue ?? (anyOpt as? AnyObject) /* anyOpt is Optional(..) and left clause of nil coalescing operator returns the unwrapped .objectValue: "123" as 'AnyObject' */ object = (anyNotOpt as? _XUOptional)?.objectValue ?? (anyNotOpt as? AnyObject) /* anyNotOpt is not optional and left-most optional chaining of left clause returns nil ('anyNotOpt as? _XUOptional' -> nil). In that case, right clause will successfully cast the non-optional 'Any' type to 'AnyObject' (with value "123") */