Проверьте, является ли переменная необязательной, и к какому типу она относится

Можно ли проверить, является ли переменная необязательной, и к какому типу она относится?

Можно проверить, является ли переменная определенной необязательной:

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

2 ответа

Поскольку протокол может быть создан как средство необязательного типа, такой же протокол может использоваться для обеспечения доступа к необязательному типу. Пример приведен в 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
}

Протокол может даже использоваться, чтобы проверить и развернуть содержащееся необязательное значение

С 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

Другие вопросы по тегам