如何在泛型中使用Nim的`of`运算符?

时间:2017-02-22 22:50:28

标签: nim

考虑一种类型层次结构,其中基础对象是非泛型的,但子类型是:

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时毫无意义。

有没有办法在不诉诸方法和动态调度的情况下一般性地解决这个问题?

1 个答案:

答案 0 :(得分:4)

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

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返回一个不透明指针,可用作该类型的标识符。您必须在哈希表中将所有派生类型及其标识符注册(您可以在程序的开头执行此操作),然后使用它来对输入值的类型信息指针进行运行时检查。 PROC。