鉴于Swift`Any`类型,我可以确定它是否是“可选”?

时间:2016-11-04 17:41:31

标签: swift

如果给出Any类型的值,是否可以检查并查看它是否为可选项? 此代码无效,因为它不是检查它是否可选,而是试图将其投射,然后通过

let a: Any = "5"

switch a {
case let optional as Optional<Any>:
    if case .some(let value) = optional {
        print("wrapped value of `\(a)` is `\(value)`")
    }

default:
    print("\(a) is not an optional")
}

基于@dfri的解决方案

private func isOptional(input: Any) -> Bool {
    let mirror = Mirror(reflecting: input)
    let style = mirror.displayStyle

    switch style {
    case .some(.optional):
        return true
    default:
        return false
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用Mirror

来使用运行时内省
let foo: String? = "foo"
let bar: String = "bar"
var a: Any = foo

// if wrapping an optional, the reflection of the value has
// a displaystyle "optional"
if let displayStyle = Mirror.init(reflecting: a).displayStyle {
    print(displayStyle) // optional
}

// for a non-optional fundamental native type: no displaystyle
a = bar
if let displayStyle = Mirror.init(reflecting: a).displayStyle {
    print(displayStyle)
} // prints nothing

可选/非可选示例,其中基础类型是用户定义的(非本机):

struct Foo {}
let foo: Foo? = Foo()
let bar: Foo = Foo()
var a: Any = foo

// if wrapping an optional, the reflection of the value has
// a displaystyle "optional"
if let displayStyle = Mirror(reflecting: a).displayStyle {
    print(displayStyle) // optional
}

// for a non-optional non-fundamental type:
a = bar
if let displayStyle = Mirror(reflecting: a).displayStyle {
    print(displayStyle) // struct
}

如果您不想使用绑定的displayStyle变量(例如用于打印),但只想检查包装的值是否是任何类型的可选,您可以向{{1}添加一个布尔子句保存if case

的可选绑定的语句
displayStyle

...或使用nil合并运算符(if let displayStyle = Mirror(reflecting: a).displayStyle, displayStyle == .optional { // is an optional ... } )完全删除绑定以支持单个条件表达式

??

但请注意,对于上述所有方法,这只是告诉您dev是if Mirror(reflecting: a).displayStyle ?? .class == .optional { // is an optional } 实例包装的类型是否可选:Swifts类型系统仍然不知道该类型。

答案 1 :(得分:0)

let a: Any = "5"
let b: Any? = "5"

if type(of: a) == Optional<Any>.self {
    print("a is optional")
} else {
    print("a is not optional")
}

if type(of: b) == Optional<Any>.self {
    print("b is optional")
} else {
    print("b is not optional")
}

/*
 a is not optional
 b is optional
*/

另一个例子......

let a: Any = 5
let b: Any? = 5
let c: Any = "5"
let d: Any? = "5"


let arr: [Any] = [a,b as Any,c,d as Any]
arr.forEach { (x) in
    print(type(of: x))
}

/*
 Int
 Optional<Any>
 String
 Optional<Any>
*/