结构的Swift动态类型检查?

时间:2016-09-19 22:18:31

标签: swift dynamic struct

我对Swift中的动态类型检查感到困惑。

具体来说,我有一个怪异的情况,我想在本质上写一个(或找到)一个函数:

func isInstanceOf(obj: Any, type: Any.Type) -> Bool

在Objective-C中,这是isKindOfClass,但这不起作用,因为Any.Type包含Swift结构,它不是类(更少NSObject个子类)。

我不能在这里使用Swift is,因为这需要硬编码类型。

我无法使用obj.dynamicType == type,因为这会忽略子类。

Swift book似乎表明此信息已丢失,根本不适用于结构:

  

类具有结构不具备的附加功能:

     

...

     
      
  • 类型转换使您可以在运行时检查和解释类实例的类型。
  •   

(在类型转换章节中,它说“Swift中的类型转换是使用is和as运算符实现的”,因此它似乎是比“{3}}更广泛的”类型转换定义。)

但是,is / as不能与结构一起使用,因为您可以将字符串和Ints放入[Any],然后将它们拉出来,并使用is Stringis Int来确定它们是什么。 Swift Book的Type Casting章就是这样做的!

是否存在与isKindOfClass一样强大但对于任何Swift实例的东西?这些信息仍然必须在运行时存在,对吗?

2 个答案:

答案 0 :(得分:6)

实际上您可以使用is运算符。

  

使用类型检查运算符(is)检查实例是否属于某个子类类型。如果实例属于该子类类型,则类型检查运算符返回true,否则返回false。

由于struct不能被子类化,因此is在应用于struct的实例时保证是一致的,因为它将检查它的静态类型,对于类,它将查询动态在运行时输入。

func `is`<T>(instance: Any, of kind: T.Type) -> Bool{
   return instance is T;
}

这项工作适用于structclass

答案 1 :(得分:1)

如前所述,是/应该可以正常使用结构。其他极端情况通常可以使用泛型函数来完成,例如:

let thing: Any = "hi" as Any

func item<T: Any>(_ item: Any, isType: T.Type) -> Bool {
    return (item as? T) != nil
}

print(item(thing, isType: String.self)) // prints "true"

不知道这是否适合您的特定用例。

更一般地说,请记住,Swift(当前)需要在编译时知道所有内容的类型。如果无法定义将传递给函数或设置为变量的特定类型,则编译器也不会。