检查变量是否为Optional,以及它包装的类型

Lop*_*Sae 13 swift

是否可以检查变量是否是可选的,以及它包装的是什么类型?

可以检查变量是否是特定的可选:

let someString: String? = "oneString"
var anyThing: Any = someString

anyThing.dynamicType // Swift.Optional<Swift.String>
anyThing.dynamicType is Optional<String>.Type // true
anyThing.dynamicType is Optional<UIView>.Type // false
Run Code Online (Sandbox Code Playgroud)

但是有可能再次检查任何类型的可选项吗?就像是:

anyThing.dynamicType is Optional.Type // fails since T cant be inferred
// or 
anyThing.dynamicType is Optional<Any>.Type // false
Run Code Online (Sandbox Code Playgroud)

一旦知道你有一个可选的,检索它包装的类型:

// hypothetical code 
anyThing.optionalType // returns String.Type
Run Code Online (Sandbox Code Playgroud)

Lop*_*Sae 8

由于可以创建协议作为无类型可选方法,因此可以使用相同的协议来提供对可选类型的访问.示例在Swift 2中,尽管它在以前的版本中应该类似:

protocol OptionalProtocol {
    func wrappedType() -> Any.Type
}

extension Optional : OptionalProtocol {
    func wrappedType() -> Any.Type {
        return Wrapped.self
    }
}

let maybeInt: Any = Optional<Int>.Some(12)
let maybeString: Any = Optional<String>.Some("maybe")

if let optional = maybeInt as? OptionalProtocol {
    print(optional.wrappedType()) // Int
    optional.wrappedType() is Int.Type // true
}

if let optional = maybeString as? OptionalProtocol {
    print(optional.wrappedType()) // String
    optional.wrappedType() is String.Type // true
}
Run Code Online (Sandbox Code Playgroud)

该协议甚至可用于检查和解包包含的可选值


rin*_*aro 7

使用Swift2.0:

let someString: String? = "oneString"
var anyThing: Any = someString

// is `Optional`
Mirror(reflecting: anyThing).displayStyle == .Optional // -> true
Run Code Online (Sandbox Code Playgroud)

但提取包裹类型并不容易.

你可以:

anyThing.dynamicType // -> Optional<String>.Type (as Any.Type)
Mirror(reflecting: anyThing).subjectType // -> Optional<String>.Type (as Any.Type)
Run Code Online (Sandbox Code Playgroud)

但我不知道如何String.TypeOptional<String>.Type包裹中提取Any.Type