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


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

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

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

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

anyThing.dynamicType is Optional.Type // fails since T cant be inferred
// or 
anyThing.dynamicType is Optional<Any>.Type // false

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

// hypothetical code 
anyThing.optionalType // returns String.Type

8868
2017-09-18 06:50


起源

无论如何,你不应该把 Optional 成 Any。看到: 如何从任何类型解包可选值? - rintaro
它可能是一个有效的案例,你可以有一个接受的功能 Any 如果它收到一个,那表现不同 Optional。 - LopSae


答案:


以来 可以创建协议作为a的手段 无类型 可选的 可以使用相同的协议来提供对可选类型的访问。示例在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
}

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


7
2017-09-25 11:27



多谢兄弟!你救了我的命! - Sanf0rd


使用Swift2.0:

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

// is `Optional`
Mirror(reflecting: anyThing).displayStyle == .Optional // -> true

但提取包装类型并不容易。

你可以:

anyThing.dynamicType // -> Optional<String>.Type (as Any.Type)
Mirror(reflecting: anyThing).subjectType // -> Optional<String>.Type (as Any.Type)

但我不知道如何提取 String.Type 从 Optional<String>.Type 包裹着 Any.Type


5
2017-09-18 11:12



到目前为止它似乎是目前无法提取的 String.Type 在......之外 Optional<String>.self。但是有可能延长 Optional 枚举提供返回包装类型的方法,并使用任何实例来访问它。 - LopSae
喜欢 这个?当你有 Optional<String>.self 如 Optional<String>.Type, 您可以。但我认为这是不可能的 Any.Type。 - rintaro
你刚刚教我如何去做:如果你有的话 let anyType: Any.Type = Array<String>.self然后把它扔掉: (anyType as! Array<String>.Type).Element.self 将返回 String.Type :) - LopSae