如何将 Nim 的 'of' 运算符与泛型一起使用?



考虑一个类型的层次结构,基本对象是非生成的,但是子类型为:

type
  TestBase = ref object of RootObj
  DerivedA = ref object of TestBase
  DerivedB[T] = ref object of TestBase
    field: T
proc testProc(x: TestBase) =
  if x of DerivedB:   # <= what to do here
    echo "it's a B!"
  else:
    echo "not a B"

使用这样的of操作员不会编译,因为期望对象类型。工作的是,例如匹配诸如DerivedB[int]之类的特定类型,或在T中制作PROC本身通用,这在DerivedA中毫无意义。

有没有办法在不诉诸方法和动态调度的情况下解决此问题?

这里最简单的解决方案是为所有通用派生类型引入虚拟基础类型,唯一的目的是协助进行此类检查。这是一个示例:

type
  TestBase = ref object of RootObj
  DerivedA = ref object of TestBase
  # I'm using illustrative names here
  # You can choose something more sensible
  DerivedDetector = ref object of TestBase
  DerivedB[T] = ref object of DerivedDetector
    field: T
proc testProc(x: TestBase) =
  if x of DerivedDetector: # This will be true for all derived types
    echo "it's a B!"
  else:
    echo "not a B"
testProc DerivedB[int](field: 10)
testProc DerivedA()

此解决方案不会增加对象的大小,并且不会在典型代码中引入任何运行时开销。

如果您无法修改继承层次结构(可能是第三方库的一部分),则基于系统模块的getTypeInfo PROC的解决方案更为复杂。该PROC返回一个不透明的指针,该指针可用作类型的标识符。您必须在哈希表中使用其标识符注册所有派生类型(您可以在程序开始时执行此操作),然后使用该标识符对其进行运行时间检查,以根据输入值的类型INFO指针进行运行时间检查Proc。

最新更新