swift2 如何在Swift中从可选类型中获取未 Package 的类型?

fnatzsnv  于 2022-11-06  发布在  Swift
关注(0)|答案(4)|浏览(210)

我试图在运行时从一个可选类型中获取一个未 Package 的类型。下面的代码将把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,我应该怎么做才能在运行时实现这一点?

dluptydi

dluptydi1#

假设您有可选的

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

没有任何反射

摘要

只要AnyAnyObject未指涉选择项,程式码就会正常运作。
对于Any,您必须先将其转换为OptionalProtocol。运行

let someVar: String?
let anyVar = someVar as Any

if let op = anyVar as? OptionalProtocol {
    print(op.wrappedType())
}

将打印

String

至于AnyObject,奇怪的是(至少对我来说),它没有转换为OptionalProtocol
原始的StackOverflow答案可以在here中找到

wz3gfoph

wz3gfoph2#

我对你的想法做了一些尝试,但我认为没有一种真实的的方法可以做到这一点,因为你还不能得到枚举的关联值的类型,因此Optional基本上是枚举,我们这里有一个问题。
我的想法是测试模型对象中所有可能的值类型。例如:

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语句链。

ecbunoof

ecbunoof3#

您可以使用bang(!)或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!)可能是你要找的。

628mspwn

628mspwn4#

如果您将值转换为非选择性的String,它会打印未 Package 的型别。

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
 }

抱歉,这很蹩脚,但你可以做这样的事情。

相关问题