【问题标题】:Check if variable is an Optional, and what type it wraps检查变量是否是可选的,以及它包装的类型
【发布时间】:2015-12-15 05:23:49
【问题描述】:

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

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

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

【问题讨论】:

  • 无论如何,您不应该将Optional 放入Any。见:How to unwrap an optional value from Any type?
  • 这可能是一个有效的例子,你可以有一个接受Any的函数,如果它接收到Optional,它的行为会有所不同。

标签: swift


【解决方案1】:

由于a protocol can be created as means of a typeless Optional 可以使用相同的协议来提供对可选类型的访问。示例在 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
}

该协议甚至可以用于check and unwrap the contained optional value

【讨论】:

  • 谢谢兄弟!你救了我的命!
【解决方案2】:

使用 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)

但我不知道如何从Optional&lt;String&gt;.Type 中提取String.Type,并用Any.Type 包裹

【讨论】:

  • 到目前为止,从Optional&lt;String&gt;.self 中提取String.Type 似乎是不可能的。但是,可以扩展 Optional 枚举以提供返回包装类型的方法,并使用任何实例来访问它。
  • 喜欢this?当您将Optional&lt;String&gt;.self 设置为Optional&lt;String&gt;.Type 时,您可以。但我认为Any.Type是不可能的。
  • 你刚刚教我怎么做:如果你有let anyType: Any.Type = Array&lt;String&gt;.self,然后把它扔回去:(anyType as! Array&lt;String&gt;.Type).Element.self 将返回String.Type :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2021-10-03
相关资源
最近更新 更多