如何从Swift中的可选类型获取未包装的类型?

Zhu*_*gqi 5 swift swift2

我正在尝试从运行时的可选类型中获取未包装的类型。以下代码将显示a的类型Optional<String>

class MySubClass: MyClass {

    var a: String? = nil
}

var a = MySubClass()

let mirror = Mirror(reflecting: a)
for child in mirror.children {
    print(child.value.dynamicType)
}
Run Code Online (Sandbox Code Playgroud)

现在,我想解开类型并获取String,我应该怎么做才能在运行时做到这一点?

mrv*_*nzo 5

假设您有一个可选的

let someVar: String?
Run Code Online (Sandbox Code Playgroud)

然后print(type(of: someVar))将打印

Optional<String>
Run Code Online (Sandbox Code Playgroud)

但是如果您将以下扩展名添加到 Optional

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

extension Optional: OptionalProtocol {
 func wrappedType() -> Any.Type {
   return Wrapped.self
 }
}
Run Code Online (Sandbox Code Playgroud)

然后print(someVar.wrappedType())将打印

String
Run Code Online (Sandbox Code Playgroud)

没有任何反射


TL; DR

只要未引用该函数,Any否则AnyObject该代码即可正常工作。

因为Any您必须将其强制转换为OptionalProtocol第一。跑步

let someVar: String?
let anyVar = someVar as Any

if let op = anyVar as? OptionalProtocol {
    print(op.wrappedType())
}
Run Code Online (Sandbox Code Playgroud)

将打印

String
Run Code Online (Sandbox Code Playgroud)


至于AnyObject(至少对我来说)奇怪的是,它并没有转换为OptionalProtocol


原始StackOverflow答案可在此处找到


Kie*_*Kie 4

我稍微考虑了一下你的想法,但我认为还没有真正的方法可以做到这一点,因为你还无法获取枚举的关联值的类型。因此可选基本上是枚举,我们这里有一个问题。

我的想法是测试模型对象中所有可能的值类型是否可以或持有。喜欢:

let myModelObject:Any? = someWayToGetTheData()
if let aString = myModelObject as? String {
    // do everything you need to store a string
} 
else if let anInteger = myModelObject as? Int {
    // do everything you need to store an integer
} 

// and so on ...
Run Code Online (Sandbox Code Playgroud)

由于您的 json 和模型必须具有预定义数量的受支持转换,这是一种可能的方式,并且据我了解您原来的问题,它基本上与测试可选枚举的动态关联值类型一样有用,这将导致也进入一系列 if-else 语句中。