我试图在运行时从可选类型中获取一个解包类型。
以下代码将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)
}
现在我想打开类型并获取String
,我该怎么做才能在运行时实现?
答案 0 :(得分:2)
我玩了一点你的想法,但我认为没有真正的方法可以做到这一点,因为你无法获得枚举的相关值的类型。因此,Optionals基本上是Enumerations,我们在这里有一个问题。
我的想法是测试模型对象中可能存在或保持的所有可能的值类型。像:
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 ...
由于您的json和您的模型必须具有预定义数量的受支持转换,这是可能的方式,并且就我理解您的原始问题而言,它基本上与测试可选枚举的动态关联值类型一样有用,这也将引入一系列if-else语句。
答案 1 :(得分:2)
假设您有一个可选
let someVar: String?
然后print(type(of: someVar))
将打印
Optional<String>
但是如果您将以下扩展名添加到Optional
protocol OptionalProtocol {
func wrappedType() -> Any.Type
}
extension Optional: OptionalProtocol {
func wrappedType() -> Any.Type {
return Wrapped.self
}
}
然后print(someVar.wrappedType())
将打印
String
完全没有反射
TL; DR
只要Any
或AnyObject
未引用该代码,代码就可以正常工作。
对于Any
,您必须先将其强制转换为OptionalProtocol
。正在运行
let someVar: String?
let anyVar = someVar as Any
if let op = anyVar as? OptionalProtocol {
print(op.wrappedType())
}
将打印
String
至于AnyObject
,奇怪的是(至少对我来说),它没有转换为OptionalProtocol
。
可以找到原始的StackOverflow答案here
答案 2 :(得分:0)
您可以使用爆炸(!
)或if let
明确展开可选项。
例如:
var foo: String? = nil
if foo == nil {
print("foo is nil")
foo = "bar"
}
let fooBang = foo!
print("fooBang: \(fooBang)")
if let ifLetFoo = foo {
print("ifLetFoo: \(ifLetFoo)")
}
这将打印:
foo is nil
fooBang: bar
ifLetFoo: bar
在您的上下文中,我认为print(child.value.dynamicType!)
可能是您正在寻找的内容。
答案 3 :(得分:0)
如果将值强制转换为非可选String,它将打印出未展开的类型。
let mirror = Mirror(reflecting: a)
for child in mirror.children {
print(String(child.value).dynamicType) //String
}
或者您可以使用String并从Optional类型中获取类型。
class MySubClass: MyClass {
var a: Int? = nil
}
var a = MySubClass()
let mirror = Mirror(reflecting: a)
for child in mirror.children {
let typeArr = String(child.value.dynamicType).characters.split{$0 == "<"}.map(String.init)
let typeArr2 = typeArr[1].characters.split{$0 == ">"}.map(String.init)
print(typeArr2[0]) // print: Int
}
对不起,这很蹩脚,但你可以这样做。